add created by
This commit is contained in:
@@ -14,6 +14,7 @@ from aws_lambda_powertools.utilities.typing import LambdaContext
|
||||
|
||||
from api_gateway import JSONResponse
|
||||
from json_encoder import JSONEncoder
|
||||
from middlewares.authentication_middleware import AuthenticationMiddleware
|
||||
from routes import courses, enrollments, orders, orgs, users
|
||||
|
||||
logger = Logger(__name__)
|
||||
@@ -32,6 +33,7 @@ app = APIGatewayHttpResolver(
|
||||
debug=debug,
|
||||
serializer=serializer,
|
||||
)
|
||||
app.use(middlewares=[AuthenticationMiddleware()])
|
||||
app.enable_swagger(path='/swagger')
|
||||
app.include_router(courses.router, prefix='/courses')
|
||||
app.include_router(enrollments.router, prefix='/enrollments')
|
||||
@@ -45,7 +47,7 @@ app.include_router(users.emails, prefix='/users')
|
||||
app.include_router(users.orgs, prefix='/users')
|
||||
app.include_router(users.password, prefix='/users')
|
||||
app.include_router(orders.router, prefix='/orders')
|
||||
app.include_router(orgs.router, prefix='/orgs')
|
||||
app.include_router(orgs.add, prefix='/orgs')
|
||||
app.include_router(orgs.admins, prefix='/orgs')
|
||||
app.include_router(orgs.custom_pricing, prefix='/orgs')
|
||||
app.include_router(orgs.scheduled, prefix='/orgs')
|
||||
@@ -59,7 +61,7 @@ def health():
|
||||
|
||||
@app.exception_handler(ServiceError)
|
||||
def exc_error(exc: ServiceError):
|
||||
logger.exception(exc)
|
||||
# logger.exception(exc)
|
||||
|
||||
return JSONResponse(
|
||||
body={
|
||||
|
||||
@@ -11,6 +11,7 @@ from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
||||
|
||||
from boto3clients import dynamodb_client
|
||||
from config import ENROLLMENT_TABLE
|
||||
from middlewares.authentication_middleware import User as Authenticated
|
||||
|
||||
logger = Logger(__name__)
|
||||
router = Router()
|
||||
@@ -33,6 +34,7 @@ def cancel(
|
||||
lock_hash: Annotated[str | None, Body(embed=True)] = None,
|
||||
):
|
||||
now_ = now()
|
||||
canceled_by: Authenticated = router.context['user']
|
||||
|
||||
with dyn.transact_writer() as transact:
|
||||
transact.update(
|
||||
@@ -55,7 +57,10 @@ def cancel(
|
||||
item={
|
||||
'id': enrollment_id,
|
||||
'sk': 'CANCELED_BY',
|
||||
'canceled_by': {},
|
||||
'canceled_by': {
|
||||
'id': canceled_by.id,
|
||||
'name': canceled_by.name,
|
||||
},
|
||||
'created_at': now_,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,14 +1,88 @@
|
||||
from decimal import Decimal
|
||||
from typing import Annotated
|
||||
|
||||
from aws_lambda_powertools import Logger
|
||||
from aws_lambda_powertools.event_handler.api_gateway import Router
|
||||
from layercake.dynamodb import DynamoDBPersistenceLayer
|
||||
from aws_lambda_powertools.event_handler.exceptions import (
|
||||
NotFoundError,
|
||||
)
|
||||
from aws_lambda_powertools.event_handler.openapi.params import Body
|
||||
from layercake.batch import BatchProcessor
|
||||
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
||||
from layercake.extra_types import CnpjStr, CpfStr, NameStr
|
||||
from pydantic import UUID4, BaseModel, EmailStr, FutureDate
|
||||
|
||||
from boto3clients import dynamodb_client
|
||||
from config import ENROLLMENT_TABLE
|
||||
from middlewares.authentication_middleware import User as Authenticated
|
||||
|
||||
logger = Logger(__name__)
|
||||
router = Router()
|
||||
dyn = DynamoDBPersistenceLayer(ENROLLMENT_TABLE, dynamodb_client)
|
||||
processor = BatchProcessor()
|
||||
|
||||
|
||||
class SubscriptionNotFoundError(NotFoundError): ...
|
||||
|
||||
|
||||
class User(BaseModel):
|
||||
id: str | UUID4
|
||||
name: NameStr
|
||||
cpf: CpfStr
|
||||
email: EmailStr
|
||||
|
||||
|
||||
class Course(BaseModel):
|
||||
id: UUID4
|
||||
name: str
|
||||
access_period: int
|
||||
unit_price: Decimal
|
||||
|
||||
|
||||
class Enrollment(BaseModel):
|
||||
user: User
|
||||
course: Course
|
||||
scheduled_for: FutureDate | None = None
|
||||
|
||||
|
||||
class Org(BaseModel):
|
||||
id: str | UUID4
|
||||
name: str
|
||||
cnpj: CnpjStr
|
||||
|
||||
|
||||
@router.post('/')
|
||||
def enroll(): ...
|
||||
def enroll(
|
||||
org_id: Annotated[UUID4 | str, Body(embed=True)],
|
||||
enrollments: Annotated[tuple[Enrollment, ...], Body(embed=True)],
|
||||
):
|
||||
created_by: Authenticated = router.context['user']
|
||||
org = dyn.collection.get_items(
|
||||
KeyPair(
|
||||
pk=str(org_id),
|
||||
sk='0',
|
||||
)
|
||||
+ KeyPair(
|
||||
pk='SUBSCRIPTION',
|
||||
sk=f'ORG#{org_id}',
|
||||
rename_key='subscription',
|
||||
)
|
||||
)
|
||||
|
||||
subscribed = 'subscription' in org
|
||||
if not subscribed:
|
||||
return checkout(Org.model_validate(org), enrollments, created_by=created_by)
|
||||
|
||||
scheduled, unscheduled = [], []
|
||||
for x in enrollments:
|
||||
(scheduled if x.scheduled_for else unscheduled).append(x)
|
||||
|
||||
print(scheduled, created_by)
|
||||
|
||||
|
||||
def checkout(
|
||||
org: Org,
|
||||
enrollments: tuple[Enrollment, ...],
|
||||
created_by: Authenticated,
|
||||
):
|
||||
print(org, enrollments, created_by)
|
||||
|
||||
@@ -1,157 +1,7 @@
|
||||
from http import HTTPStatus
|
||||
from typing import Annotated
|
||||
from uuid import uuid4
|
||||
|
||||
from aws_lambda_powertools.event_handler.api_gateway import Router
|
||||
from aws_lambda_powertools.event_handler.exceptions import NotFoundError
|
||||
from aws_lambda_powertools.event_handler.openapi.params import Body
|
||||
from layercake.dateutils import now
|
||||
from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair
|
||||
from layercake.extra_types import CnpjStr, NameStr
|
||||
from pydantic import UUID4, BaseModel, EmailStr
|
||||
|
||||
from api_gateway import JSONResponse
|
||||
from boto3clients import dynamodb_client
|
||||
from config import INTERNAL_EMAIL_DOMAIN, USER_TABLE
|
||||
from exceptions import ConflictError
|
||||
|
||||
from .add import router as add
|
||||
from .admins import router as admins
|
||||
from .custom_pricing import router as custom_pricing
|
||||
from .enrollments.scheduled import router as scheduled
|
||||
from .users import router as users
|
||||
|
||||
router = Router()
|
||||
dyn = DynamoDBPersistenceLayer(USER_TABLE, dynamodb_client)
|
||||
|
||||
|
||||
__all__ = ['admins', 'custom_pricing', 'scheduled', 'users']
|
||||
|
||||
|
||||
class CNPJConflictError(ConflictError): ...
|
||||
|
||||
|
||||
class EmailConflictError(ConflictError): ...
|
||||
|
||||
|
||||
class UserNotFoundError(NotFoundError): ...
|
||||
|
||||
|
||||
class EmailNotFoundError(NotFoundError): ...
|
||||
|
||||
|
||||
class User(BaseModel):
|
||||
id: str | UUID4
|
||||
name: NameStr
|
||||
email: EmailStr
|
||||
|
||||
|
||||
@router.post('/')
|
||||
def add_org(
|
||||
name: Annotated[str, Body(embed=True)],
|
||||
cnpj: Annotated[CnpjStr, Body(embed=True)],
|
||||
user: Annotated[User, Body(embed=True)],
|
||||
):
|
||||
now_ = now()
|
||||
org_id = str(uuid4())
|
||||
email = f'org+{cnpj}@{INTERNAL_EMAIL_DOMAIN}'
|
||||
|
||||
with dyn.transact_writer() as transact:
|
||||
transact.put(
|
||||
item={
|
||||
# Post-migration (users): rename `cnpj` to `CNPJ`
|
||||
'id': 'cnpj',
|
||||
'sk': cnpj,
|
||||
'org_id': org_id,
|
||||
'created_at': now_,
|
||||
},
|
||||
cond_expr='attribute_not_exists(sk)',
|
||||
exc_cls=CNPJConflictError,
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
# Post-migration (users): rename `email` to `EMAIL`
|
||||
'id': 'email',
|
||||
'sk': email,
|
||||
'user_id': org_id,
|
||||
'created_at': now_,
|
||||
},
|
||||
cond_expr='attribute_not_exists(sk)',
|
||||
exc_cls=EmailConflictError,
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': org_id,
|
||||
'sk': '0',
|
||||
'name': name,
|
||||
'email': email,
|
||||
'cnpj': cnpj,
|
||||
'created_at': now_,
|
||||
}
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': org_id,
|
||||
# Post-migration: rename `emails` to `EMAIL`
|
||||
'sk': f'emails#{email}',
|
||||
'email_primary': True,
|
||||
'email_verified': True,
|
||||
'mx_record_exists': True,
|
||||
'created_at': now_,
|
||||
}
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': org_id,
|
||||
# Post-migration (users): rename `admins#` to `ADMIN#`
|
||||
'sk': f'admins#{user.id}',
|
||||
'name': user.name,
|
||||
'email': user.email,
|
||||
'created_at': now_,
|
||||
}
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': user.id,
|
||||
# Post-migration (users): rename `orgs#` to `ORG#`
|
||||
'sk': f'orgs#{org_id}',
|
||||
'name': name,
|
||||
'cnpj': cnpj,
|
||||
'created_at': now_,
|
||||
}
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': user.id,
|
||||
'sk': f'SCOPE#{org_id}',
|
||||
'scope': {'apps:admin'},
|
||||
'created_at': now_,
|
||||
}
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
# Post-migration (users): rename `orgmembers#` to `MEMBER#ORG#`
|
||||
'id': f'orgmembers#{org_id}',
|
||||
'sk': user.id,
|
||||
'created_at': now_,
|
||||
}
|
||||
)
|
||||
transact.condition(
|
||||
key=KeyPair(str(user.id), '0'),
|
||||
cond_expr='attribute_exists(sk)',
|
||||
exc_cls=UserNotFoundError,
|
||||
)
|
||||
transact.condition(
|
||||
# Post-migration (users): rename `email` to `EMAIL`
|
||||
key=KeyPair('email', user.email),
|
||||
cond_expr='attribute_exists(sk)',
|
||||
exc_cls=EmailNotFoundError,
|
||||
)
|
||||
|
||||
return JSONResponse(
|
||||
status_code=HTTPStatus.CREATED,
|
||||
body={
|
||||
'id': org_id,
|
||||
'name': name,
|
||||
'email': email,
|
||||
},
|
||||
)
|
||||
__all__ = ['add', 'admins', 'custom_pricing', 'scheduled', 'users']
|
||||
|
||||
@@ -14,6 +14,7 @@ from api_gateway import JSONResponse
|
||||
from boto3clients import dynamodb_client
|
||||
from config import INTERNAL_EMAIL_DOMAIN, USER_TABLE
|
||||
from exceptions import ConflictError
|
||||
from middlewares.authentication_middleware import User as Authenticated
|
||||
|
||||
router = Router()
|
||||
dyn = DynamoDBPersistenceLayer(USER_TABLE, dynamodb_client)
|
||||
@@ -53,8 +54,9 @@ def add(
|
||||
org: Annotated[Org, Body(embed=True)],
|
||||
):
|
||||
org.id = org_id
|
||||
created_by: Authenticated = router.context['user']
|
||||
|
||||
if _create_user(user, org):
|
||||
if _create_user(user, org, created_by):
|
||||
return JSONResponse(HTTPStatus.CREATED)
|
||||
|
||||
user_id = _get_user_id(user)
|
||||
@@ -101,7 +103,11 @@ def unlink(org_id: str, user_id: str):
|
||||
return JSONResponse(HTTPStatus.NO_CONTENT)
|
||||
|
||||
|
||||
def _create_user(user: User, org: Org) -> bool:
|
||||
def _create_user(
|
||||
user: User,
|
||||
org: Org,
|
||||
created_by: Authenticated,
|
||||
) -> bool:
|
||||
now_ = now()
|
||||
user_id = uuid4()
|
||||
email_verified = INTERNAL_EMAIL_DOMAIN in user.email
|
||||
@@ -130,6 +136,17 @@ def _create_user(user: User, org: Org) -> bool:
|
||||
'created_at': now_,
|
||||
}
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': user_id,
|
||||
'sk': 'CREATED_BY',
|
||||
'created_by': {
|
||||
'id': created_by.id,
|
||||
'name': created_by.name,
|
||||
},
|
||||
'created_at': now_,
|
||||
}
|
||||
)
|
||||
transact.put(
|
||||
item={
|
||||
'id': user_id,
|
||||
|
||||
Reference in New Issue
Block a user