This repository has been archived by the owner on Apr 14, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
part of change_password logic (#249)
- Loading branch information
Showing
15 changed files
with
148 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from pydantic import constr | ||
|
||
Password = constr(pattern=r"^[\w\(\)\[\]\{\}\^\$\+\*@#%!&]{8,}$") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
import asyncio | ||
import uuid | ||
from typing import Any, Iterable | ||
|
||
import aiosmtplib | ||
import backoff | ||
from facet import ServiceMixin | ||
from pydantic import EmailStr | ||
|
||
from .settings import Settings | ||
from .templates import Template | ||
|
@@ -35,16 +35,10 @@ def __init__( | |
def templates(self) -> dict[str, Template]: | ||
return self._templates | ||
|
||
async def _get_recipient_email(self, recipient: uuid.UUID) -> str: | ||
# Issue: Write a function to get email from the users service using user_id | ||
|
||
return "[email protected]" | ||
|
||
async def send(self, template: Template, data: dict[str, Any], recipients: Iterable[uuid.UUID]): | ||
async def send(self, template: Template, data: dict[str, Any], recipients: Iterable[EmailStr]): | ||
coroutines = [] | ||
for recipient in recipients: | ||
recipient_email = await self._get_recipient_email(recipient) | ||
message = template.render(recipient=recipient_email, sender=self._sender, data=data) | ||
message = template.render(recipient=recipient, sender=self._sender, data=data) | ||
coroutine = backoff.on_exception(backoff.expo, Exception, max_tries=3)( | ||
self._client.send_message, | ||
)(message) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,25 @@ | ||
from pydantic import BaseModel, EmailStr, constr | ||
from pydantic import BaseModel, EmailStr | ||
|
||
from sapphire.common.types import Password | ||
from sapphire.users.api.rest.schemas import UserResponse | ||
|
||
|
||
class AuthorizeRequest(BaseModel): | ||
email: EmailStr | ||
password: constr(pattern=r"^[\w\(\)\[\]\{\}\^\$\+\*@#%!&]{8,}$") | ||
password: Password | ||
|
||
|
||
class AuthorizeResponse(BaseModel): | ||
user: UserResponse | ||
access_token: str | ||
refresh_token: str | ||
|
||
|
||
class ResetPasswordRequest(BaseModel): | ||
email: EmailStr | ||
|
||
|
||
class ChangePasswordRequest(BaseModel): | ||
code: str | ||
email: EmailStr | ||
new_password: Password |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from .service import Service, get_service | ||
from .settings import Settings |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import asyncio | ||
|
||
from pydantic import EmailStr | ||
|
||
from sapphire.common.broker.models.email import Email, EmailType | ||
from sapphire.common.broker.service import BaseBrokerProducerService | ||
|
||
from .settings import Settings | ||
|
||
|
||
class Service(BaseBrokerProducerService): | ||
async def send_email_code(self, email: EmailStr, code: str, topic: str = "email"): | ||
await self.send( | ||
topic=topic, | ||
message=Email( | ||
to=[email], | ||
type=EmailType.RESET_PASSWORD, | ||
sending_data={"code": code} | ||
) | ||
) | ||
|
||
|
||
def get_service( | ||
loop: asyncio.AbstractEventLoop, | ||
settings: Settings, | ||
) -> Service: | ||
return Service(loop=loop, servers=settings.servers) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from sapphire.common.broker.settings import BaseBrokerProducerSettings | ||
|
||
|
||
class Settings(BaseBrokerProducerSettings): | ||
servers: list[str] = ["localhost:9091"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,42 @@ | ||
import secrets | ||
import uuid | ||
|
||
from pydantic import EmailStr | ||
|
||
from sapphire.common.cache.service import BaseCacheService | ||
|
||
from .settings import Settings | ||
|
||
|
||
class Service(BaseCacheService): | ||
async def set_state(self) -> str: | ||
state = secrets.token_hex(32) | ||
async def oauth_set_state(self) -> str: | ||
state = str(uuid.uuid4()) | ||
key = f"users:auth:oauth2:habr:state:{state}" | ||
await self.redis.set(key, state, ex=120) | ||
await self.redis.set(key, state, ex=Settings.oauth_storage_time) | ||
return state | ||
|
||
async def validate_state(self, state: str) -> bool: | ||
async def oauth_validate_state(self, state: str) -> bool: | ||
key = f"users:auth:oauth2:habr:state:{state}" | ||
value = await self.redis.get(key) | ||
if value is not None: | ||
await self.redis.delete(key) | ||
return True | ||
return False | ||
|
||
async def change_password_set_secret_code(self, email: EmailStr) -> str: | ||
secret_code = str(secrets.token_urlsafe(12)) # generate sixteen-digit secret code | ||
key = f"users:auth:change_password:secret_code:{email}" | ||
await self.redis.set(key, secret_code, ex=Settings.code_storage_time) | ||
return secret_code | ||
|
||
async def reset_password_validate_code(self, secret_code: str, email: EmailStr) -> bool: | ||
key = f"users:auth:change_password:secret_code:{email}" | ||
value = await self.redis.get(key) | ||
if value == secret_code: | ||
await self.redis.delete(key) | ||
return True | ||
return False | ||
|
||
|
||
def get_service(settings: Settings) -> Service: | ||
return Service(url=str(settings.url)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,4 +2,5 @@ | |
|
||
|
||
class Settings(BaseCacheSettings): | ||
pass | ||
oauth_storage_time: int = 120 | ||
code_storage_time: int = 43200 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters