add lookup

This commit is contained in:
2025-12-01 22:27:14 -03:00
parent f3e3d9f8c2
commit 8eb5427af4
22 changed files with 548 additions and 133 deletions

View File

@@ -9,9 +9,12 @@ from aws_lambda_powertools.utilities.typing import LambdaContext
from routes.authentication import router as authentication
from routes.authorize import router as authorize
from routes.forgot import router as forgot
from routes.jwks import router as jwks
from routes.lookup import router as lookup
from routes.openid_configuration import router as openid_configuration
from routes.register import router as register
from routes.reset import router as reset
from routes.revoke import router as revoke
from routes.token import router as token
from routes.userinfo import router as userinfo
@@ -21,9 +24,12 @@ tracer = Tracer()
app = APIGatewayHttpResolver(enable_validation=True)
app.include_router(authentication)
app.include_router(authorize)
app.include_router(forgot)
app.include_router(jwks)
app.include_router(lookup)
app.include_router(openid_configuration)
app.include_router(register)
app.include_router(reset)
app.include_router(revoke)
app.include_router(token)
app.include_router(userinfo)

View File

@@ -0,0 +1,12 @@
from typing import Annotated
from aws_lambda_powertools.event_handler.api_gateway import Router
from aws_lambda_powertools.event_handler.openapi.params import Body
from pydantic import EmailStr
router = Router()
@router.post('/forgot')
def forgot(email: Annotated[EmailStr, Body(embed=True)]):
return {}

View File

@@ -0,0 +1,49 @@
from typing import Annotated
from aws_lambda_powertools.event_handler.api_gateway import Router
from aws_lambda_powertools.event_handler.openapi.params import Path
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, SortKey, TransactKey
from layercake.extra_types import CnpjStr, CpfStr
from layercake.funcs import pick
from pydantic import EmailStr
from boto3clients import dynamodb_client
from config import OAUTH2_TABLE
router = Router()
dyn = DynamoDBPersistenceLayer(OAUTH2_TABLE, dynamodb_client)
@router.get('/lookup')
def lookup(
email: Annotated[EmailStr, Path] = 'unknown',
cpf: Annotated[CpfStr, Path] = 'unknown',
cnpj: Annotated[CnpjStr, Path] = 'unknown',
):
r = dyn.collection.get_items(
KeyPair(
pk='email',
sk=SortKey(email, path_spec='user_id'),
rename_key='id',
)
+ KeyPair(
pk='cpf',
sk=SortKey(cpf, path_spec='user_id'),
rename_key='id',
)
+ KeyPair(
pk='cnpj',
sk=SortKey(cnpj, path_spec='user_id'),
rename_key='org_id',
),
flatten_top=False,
)
if 'id' in r:
user = dyn.collection.get_items(
TransactKey(r['id']) + SortKey('0') + SortKey('FRESH_USER')
)
return r | pick(('name', 'email'), user) if 'FRESH_USER' in user else {}
return r

View File

@@ -1,8 +1,41 @@
from http import HTTPStatus
from typing import Annotated
from aws_lambda_powertools.event_handler.api_gateway import Router
from aws_lambda_powertools.event_handler.exceptions import ServiceError
from aws_lambda_powertools.event_handler.openapi.params import Body
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair, SortKey
from layercake.extra_types import CnpjStr, CpfStr, NameStr
from pydantic import BaseModel, EmailStr
from boto3clients import dynamodb_client
from config import OAUTH2_TABLE
router = Router()
dyn = DynamoDBPersistenceLayer(OAUTH2_TABLE, dynamodb_client)
class UserConflictError(ServiceError):
def __init__(self, msg: str | dict):
super().__init__(HTTPStatus.CONFLICT, msg)
class Org(BaseModel):
id: str | None
name: str
cnpj: CnpjStr
@router.get('/register')
def register():
def register(
name: Annotated[NameStr, Body(embed=True)],
email: Annotated[EmailStr, Body(embed=True)],
password: Annotated[str, Body(min_length=6, embed=True)],
cpf: Annotated[CpfStr, Body(embed=True)],
user_id: Annotated[str | None, Body(embed=True)] = None,
org: Annotated[Org | None, Body(embed=True)] = None,
):
if user_id:
...
return {}

View File

@@ -0,0 +1,14 @@
from typing import Annotated
from aws_lambda_powertools.event_handler.api_gateway import Router
from aws_lambda_powertools.event_handler.openapi.params import Body, Path
router = Router()
@router.post('/reset')
def reset(
new_password: Annotated[str, Body(min_length=6, embed=True)],
code: Annotated[str, Path],
):
return {}

View File

@@ -68,6 +68,24 @@ Resources:
Path: /register
Method: POST
ApiId: !Ref HttpApi
Forgot:
Type: HttpApi
Properties:
Path: /forgot
Method: POST
ApiId: !Ref HttpApi
Reset:
Type: HttpApi
Properties:
Path: /reset
Method: POST
ApiId: !Ref HttpApi
Lookup:
Type: HttpApi
Properties:
Path: /lookup
Method: GET
ApiId: !Ref HttpApi
Authorize:
Type: HttpApi
Properties:

View File

@@ -0,0 +1,30 @@
from http import HTTPMethod
from layercake.dynamodb import DynamoDBPersistenceLayer, PartitionKey
from ..conftest import HttpApiProxy, LambdaContext
def test_register(
app,
seeds,
dynamodb_persistence_layer: DynamoDBPersistenceLayer,
http_api_proxy: HttpApiProxy,
lambda_context: LambdaContext,
):
r = app.lambda_handler(
http_api_proxy(
raw_path='/register',
method=HTTPMethod.POST,
body={
'name': '07879819908',
},
),
lambda_context,
)
assert len(r['cookies']) == 1
session = dynamodb_persistence_layer.collection.query(PartitionKey('SESSION'))
# One seesion if created from seeds
assert len(session['items']) == 2