Enforce trading authorization and suitability checks
This commit is contained in:
@@ -30,13 +30,20 @@ from app.api.dependencies.database import get_session
|
||||
from app.api.schemas.trading import OrderCreateRequest
|
||||
from app.api.views.envelope import envelope, list_envelope
|
||||
from app.core.contracts import RequestContext
|
||||
from app.service.authorization_service import AuthorizationService
|
||||
from app.service.suitability_service import SuitabilityService
|
||||
from app.service.trade_service import TradeService
|
||||
|
||||
router = APIRouter(prefix="/api/v1/users/me", tags=["trading"])
|
||||
|
||||
|
||||
def _service(session: AsyncSession, context: RequestContext) -> TradeService:
|
||||
return TradeService(session)
|
||||
return TradeService(session, suitability_evaluator=SuitabilityService())
|
||||
|
||||
|
||||
async def _authorize(context: RequestContext, permission: str) -> None:
|
||||
"""Enforce the endpoint permission declared in docs/05 before DB work."""
|
||||
await AuthorizationService.require(context, permission)
|
||||
|
||||
|
||||
# T001 账户看板
|
||||
@@ -45,6 +52,7 @@ async def get_account_dashboard(
|
||||
context: RequestContext = Depends(build_request_context), # noqa: B008
|
||||
session: AsyncSession = Depends(get_session), # noqa: B008
|
||||
) -> dict[str, object]:
|
||||
await _authorize(context, "account:read:self")
|
||||
data = await _service(session, context).get_account_dashboard(context)
|
||||
return envelope(data, context)
|
||||
|
||||
@@ -56,6 +64,7 @@ async def submit_order(
|
||||
context: RequestContext = Depends(build_request_context), # noqa: B008
|
||||
session: AsyncSession = Depends(get_session), # noqa: B008
|
||||
) -> dict[str, object]:
|
||||
await _authorize(context, "trade:order:create")
|
||||
data = await _service(session, context).submit_order(payload, context)
|
||||
return envelope(data, context)
|
||||
|
||||
@@ -68,6 +77,7 @@ async def list_orders(
|
||||
context: RequestContext = Depends(build_request_context), # noqa: B008
|
||||
session: AsyncSession = Depends(get_session), # noqa: B008
|
||||
) -> dict[str, object]:
|
||||
await _authorize(context, "trade:order:read")
|
||||
cursor_id = int(cursor) if cursor else None
|
||||
items, next_cursor = await _service(session, context).list_orders(
|
||||
context, limit=limit, cursor=cursor_id
|
||||
@@ -85,6 +95,7 @@ async def get_order(
|
||||
context: RequestContext = Depends(build_request_context), # noqa: B008
|
||||
session: AsyncSession = Depends(get_session), # noqa: B008
|
||||
) -> dict[str, object]:
|
||||
await _authorize(context, "trade:order:read")
|
||||
data = await _service(session, context).get_order(order_no, context)
|
||||
return envelope(data, context)
|
||||
|
||||
@@ -96,6 +107,7 @@ async def cancel_order(
|
||||
context: RequestContext = Depends(build_request_context), # noqa: B008
|
||||
session: AsyncSession = Depends(get_session), # noqa: B008
|
||||
) -> dict[str, object]:
|
||||
await _authorize(context, "trade:order:cancel")
|
||||
order = await _service(session, context).cancel_order(order_no, context)
|
||||
return envelope(order, context)
|
||||
|
||||
@@ -106,6 +118,7 @@ async def list_holdings(
|
||||
context: RequestContext = Depends(build_request_context), # noqa: B008
|
||||
session: AsyncSession = Depends(get_session), # noqa: B008
|
||||
) -> dict[str, object]:
|
||||
await _authorize(context, "holding:read:self")
|
||||
data = await _service(session, context).list_holdings(context)
|
||||
return envelope(data, context)
|
||||
|
||||
@@ -118,6 +131,7 @@ async def list_transactions(
|
||||
context: RequestContext = Depends(build_request_context), # noqa: B008
|
||||
session: AsyncSession = Depends(get_session), # noqa: B008
|
||||
) -> dict[str, object]:
|
||||
await _authorize(context, "trade:txn:read")
|
||||
cursor_id = int(cursor) if cursor else None
|
||||
data = await _service(session, context).list_transactions(
|
||||
context, limit=limit, cursor=cursor_id
|
||||
@@ -132,6 +146,7 @@ async def get_transaction(
|
||||
context: RequestContext = Depends(build_request_context), # noqa: B008
|
||||
session: AsyncSession = Depends(get_session), # noqa: B008
|
||||
) -> dict[str, object]:
|
||||
await _authorize(context, "trade:txn:read")
|
||||
item = await _service(session, context).get_transaction(txn_no, context)
|
||||
return envelope(item, context)
|
||||
|
||||
@@ -144,8 +159,9 @@ async def list_cash_ledger(
|
||||
context: RequestContext = Depends(build_request_context), # noqa: B008
|
||||
session: AsyncSession = Depends(get_session), # noqa: B008
|
||||
) -> dict[str, object]:
|
||||
await _authorize(context, "account:read:self")
|
||||
cursor_id = int(cursor) if cursor else None
|
||||
data = await _service(session, context).list_cash_ledger(
|
||||
context, limit=limit, cursor=cursor_id
|
||||
)
|
||||
return envelope(data, context)
|
||||
return envelope(data, context)
|
||||
|
||||
Reference in New Issue
Block a user