main
py 75 lines 3.27 KB
Raw
1 from typing import Optional
2
3 from fastapi import APIRouter
4 from fastapi import Depends
5 from fastapi import HTTPException
6 from fastapi import Query
7 from fastapi import Security
8 from loguru import logger
9 from sqlalchemy.ext.asyncio import AsyncSession
10
11 from app.auth.models.users import User
12 from app.auth.utils import AuthHandler
13 from app.db.db_session import get_db
14 from app.middleware.customer_access import customer_access_handler
15 from app.siem.schema.events import EventsQueryParams
16 from app.siem.schema.events import EventsQueryResponse
17 from app.siem.schema.events import FieldMappingsResponse
18 from app.siem.services.events import get_field_mappings
19 from app.siem.services.events import query_events
20
21 siem_events_router = APIRouter()
22
23
24 @siem_events_router.get(
25 "/{customer_code}/{source_name}",
26 response_model=EventsQueryResponse,
27 description="Query events from a customer's event source with scroll-based pagination and optional Lucene query",
28 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst", "customer_user"))],
29 )
30 async def query_events_endpoint(
31 customer_code: str,
32 source_name: str,
33 timerange: str = Query("24h", description="Time range (e.g. '1h', '24h', '7d', '1w')"),
34 page_size: int = Query(50, ge=1, le=1000, description="Number of results per page"),
35 scroll_id: Optional[str] = Query(None, description="Scroll ID for fetching the next page"),
36 query: Optional[str] = Query(None, description="Lucene query string (e.g. 'agent_name:piHole AND agent_id:088')"),
37 time_from: Optional[str] = Query(None, description="Absolute start time in ISO format. Overrides timerange."),
38 time_to: Optional[str] = Query(None, description="Absolute end time in ISO format. Overrides timerange."),
39 current_user: User = Depends(AuthHandler().get_current_user),
40 db: AsyncSession = Depends(get_db),
41 ) -> EventsQueryResponse:
42 logger.info(f"Querying events for customer {customer_code}, source {source_name}")
43
44 if not await customer_access_handler.check_customer_access(current_user, customer_code, db):
45 raise HTTPException(status_code=403, detail=f"Access denied to customer {customer_code}")
46
47 params = EventsQueryParams(
48 timerange=timerange,
49 page_size=page_size,
50 scroll_id=scroll_id,
51 query=query,
52 time_from=time_from,
53 time_to=time_to,
54 )
55 return await query_events(customer_code, source_name, params, db)
56
57
58 @siem_events_router.get(
59 "/{customer_code}/{source_name}/fields",
60 response_model=FieldMappingsResponse,
61 description="Get index field name mappings for a customer's event source to assist with building queries",
62 dependencies=[Security(AuthHandler().require_any_scope("admin", "analyst", "customer_user"))],
63 )
64 async def get_field_mappings_endpoint(
65 customer_code: str,
66 source_name: str,
67 current_user: User = Depends(AuthHandler().get_current_user),
68 db: AsyncSession = Depends(get_db),
69 ) -> FieldMappingsResponse:
70 logger.info(f"Getting field mappings for customer {customer_code}, source {source_name}")
71
72 if not await customer_access_handler.check_customer_access(current_user, customer_code, db):
73 raise HTTPException(status_code=403, detail=f"Access denied to customer {customer_code}")
74
75 return await get_field_mappings(customer_code, source_name, db)