from http import HTTPStatus 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 layercake.dateutils import now from layercake.dynamodb import DynamoDBPersistenceLayer, KeyPair from layercake.extra_types import NameStr from pydantic import BaseModel, EmailStr from api_gateway import JSONResponse from boto3clients import dynamodb_client from config import USER_TABLE router = Router() user_layer = DynamoDBPersistenceLayer(USER_TABLE, dynamodb_client) @router.get('//admins', compress=True) def admins(id: str): return user_layer.collection.query( KeyPair(id, 'admins'), limit=100, ) class Admin(BaseModel): id: str name: NameStr email: EmailStr @router.post('//admins', compress=True) def grant(id: str, admin: Admin): now_ = now() with user_layer.transact_writer() as transact: transact.condition( key=KeyPair(f'orgmembers#{id}', admin.id), cond_expr='attribute_exists(sk)', ) # Grant admin privileges transact.put( item={ 'id': admin.id, 'sk': f'acls#{id}', 'roles': ['ADMIN'], 'created_ad': now_, }, # cond_expr='attribute_not_exists(sk)', ) # Add user to admin list transact.put( item={ 'id': id, 'sk': f'admins#{admin.id}', 'name': admin.name, 'email': admin.email, 'created_ad': now_, }, cond_expr='attribute_not_exists(sk)', ) return JSONResponse(status_code=HTTPStatus.CREATED) @router.delete('//admins', compress=True) def revoke( id: str, user_id: Annotated[str, Body(embed=True)], ): with user_layer.transact_writer() as transact: # Revoke admin privileges transact.delete(key=KeyPair(user_id, f'acls#{id}')) # Remove user from admin list transact.delete(key=KeyPair(id, f'admins#{user_id}')) return JSONResponse(status_code=HTTPStatus.OK)