Skip to content

Commit

Permalink
- BaseSmsService.verify_code_and_clear divided into two separate methods
Browse files Browse the repository at this point in the history
  • Loading branch information
onstabb committed Dec 23, 2023
1 parent 850e824 commit 93d9f9b
Show file tree
Hide file tree
Showing 12 changed files with 26 additions and 31 deletions.
1 change: 0 additions & 1 deletion requirements-base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ apscheduler~=3.10.4
pymongo~=4.6.1
python-multipart~=0.0.6
pytz~=2023.3
vincenty~=0.1.4
sse-starlette~=1.8.2
boto3~=1.29.6
starlette-admin~=0.12.2
Expand Down
16 changes: 8 additions & 8 deletions src/authorization/routers.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
from fastapi import APIRouter, Header, HTTPException, status

import config as global_config

import security
from authorization import service
from authorization.schemas import (
SignUpDataIn, TokenDataOut, SmsConfirmationDataIn, SmsConfirmationDataOut, UserCredentialsIn
)
from authorization.smsservice.telesign import TelesignService
from users.models import User
from security import generate_password, hash_password



router: APIRouter = APIRouter(tags=['Authorization'])
Expand All @@ -29,11 +29,12 @@ def sign_up(

@router.post("/confirm-sms", response_model=TokenDataOut)
def confirm_sms(data: SmsConfirmationDataIn):
if not TelesignService.verify_code_and_clear(data.phone_number, data.sms_code):
if not TelesignService.verified(data.phone_number, data.sms_code):
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail=f'SMS-code is invalid')

generated_password: str = generate_password()
hashed_password = hash_password(generated_password)
TelesignService.clear(data.phone_number)
generated_password: str = security.generate_password()
hashed_password = security.hash_password(generated_password)

user: User | None = service.get_user_by_phone_number(data.phone_number)
user = (
Expand All @@ -48,9 +49,8 @@ def confirm_sms(data: SmsConfirmationDataIn):
def login(user_in: UserCredentialsIn):
user: User | None = service.get_user_by_phone_number(user_in.phone_number)
if not user or not user.check_password(user_in.password.get_secret_value()):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid phone number or password",
)
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid phone number or password")

token, expires_at = user.token
return TokenDataOut(access_token=token, new_password=None, expires_at=expires_at)

13 changes: 5 additions & 8 deletions src/authorization/smsservice/baseservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,9 @@ def _clear_task(cls, task_key: MobilePhoneNumber) -> None:
job: Job | None = scheduler.get_job(task_key, jobstore="sms_service")
if job:
scheduler.remove_job(task_key, jobstore="sms_service")
cls._storage.pop(task_key, "")

@classmethod
def _store_temporary_code(cls, code: SmsCode, phone_number: MobilePhoneNumber) -> datetime:

cls._clear_task(phone_number)
cls._storage[phone_number] = code

Expand All @@ -47,14 +45,13 @@ def _store_temporary_code(cls, code: SmsCode, phone_number: MobilePhoneNumber) -
return expires_at

@classmethod
def verify_code_and_clear(cls, phone_number: MobilePhoneNumber, code: SmsCode) -> bool:

verifying_code: SmsCode = cls._storage.get(phone_number, "")
if verifying_code != code:
return False
def verified(cls, phone_number: MobilePhoneNumber, code: SmsCode) -> bool:
return cls._storage.get(phone_number, "") == code

@classmethod
def clear(cls, phone_number: MobilePhoneNumber) -> None:
cls._clear_task(phone_number)
return True
cls._storage.pop(phone_number, "")

@classmethod
def __remove_code(cls, phone_number: MobilePhoneNumber) -> None:
Expand Down
2 changes: 1 addition & 1 deletion src/candidates/routers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@

@router.get("", response_model=list[UserPublicOut])
def get_candidates(current_profile: CurrentActiveCompletedUser):
return service.get_candidates_for_user(current_profile)
return service.get_candidates_by_user(current_profile)
2 changes: 1 addition & 1 deletion src/candidates/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from users.models import User


def get_candidates_for_user(user: User, limit: int = 1) -> list[dict]:
def get_candidates_by_user(user: User, limit: int = 1) -> list[dict]:
match_query = {
"is_active": True,
"banned": False,
Expand Down
1 change: 1 addition & 0 deletions src/photos/bucket/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ class BaseBucket(ABC):

@abstractmethod
def upload(self, file: typing.BinaryIO, filename: str, **kwargs) -> str:
""" This function must upload provided file to bucket storage and return the URL access to this file"""
pass
3 changes: 1 addition & 2 deletions src/photos/routers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
@router.put("/{list_index}", response_model=UserPrivateOut)
def update_profile_photo(
photo: UploadFile,
response: Response,
current_user: CurrentActiveUser,
response: Response,
list_index: int = Path(lt=config.MAX_USER_PHOTOS, ge=0),
):
if list_index > len(current_user.photo_urls):
Expand Down Expand Up @@ -44,7 +44,6 @@ def update_profile_photo(
filename=helpers.filename_token_encode(extension, user_id=str(current_user.id), index=list_index),
ContentType=photo.content_type
)

response.status_code = status.HTTP_201_CREATED if len(current_user.photo_urls) == list_index else status.HTTP_200_OK
service.upsert_photo_url(image_url, user=current_user, index=list_index)
return current_user
3 changes: 2 additions & 1 deletion src/userprofile/routers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"",
response_model=UserPrivateOut,
responses={
status.HTTP_200_OK: {"detail": "Profile updated"}, status.HTTP_201_CREATED: {"detail": "Profile created"},
status.HTTP_200_OK: {"detail": "Profile updated"},
status.HTTP_201_CREATED: {"detail": "Profile created"},
},
)
def upsert_profile(profile_data: PrivateUserProfileIn, response: Response, user: CurrentActiveUser):
Expand Down
2 changes: 1 addition & 1 deletion src/users/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@



def get_current_user_by_token(subject: str = Depends(JWTBearer), ) -> User:
def get_current_user_by_token(subject: str = Depends(JWTBearer),) -> User:
user: User | None = service.get_user_by_id(user_id=subject)
if not user:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid token")
Expand Down
1 change: 0 additions & 1 deletion src/users/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
ReferenceField,
)


from datehelpers import get_aware_datetime_now
from models import BaseDocument
from userprofile.models import UserProfile
Expand Down
11 changes: 5 additions & 6 deletions tests/test_authorization/test_smsservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,12 @@ def test_send_sms_expiration_task_created(phone_number, scheduler):
assert scheduler.get_job(phone_number)


def test_verify_and_clear_correct_code(phone_number):
def test_verified(phone_number):
code = BaseSmsService.get_code(phone_number)
assert BaseSmsService.verify_code_and_clear(phone_number, code)
assert not BaseSmsService.verify_code_and_clear(phone_number, code)
assert BaseSmsService.verified(phone_number, code)


def test_verify_and_clear_incorrect_code(phone_number):
def test_not_verified(phone_number):
code = BaseSmsService.get_code(phone_number)
assert not BaseSmsService.verify_code_and_clear(phone_number, "wrong")
assert BaseSmsService.verify_code_and_clear(phone_number, code)
BaseSmsService.clear(phone_number)
assert not BaseSmsService.verified(phone_number, code)
2 changes: 1 addition & 1 deletion tests/test_candidates/test_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def test_get_candidates_for_user(user_factory, contact_factory):
user = user_factory.create(profile__gender_preference=None)
existed_contact = contact_factory.create(initiator=user, respondent__profile__gender_preference=None)

result = service.get_candidates_for_user(user, limit=5)
result = service.get_candidates_by_user(user, limit=5)

for first, second in pairwise(result):
assert first["profile"]["distance"] <= second["profile"]["distance"]
Expand Down

0 comments on commit 93d9f9b

Please sign in to comment.