From 8d4f0ba1c6d309ac31f056b52c563d99aa0e74c4 Mon Sep 17 00:00:00 2001 From: Cecilia Stevens <63068179+ceciliastevens@users.noreply.github.com> Date: Mon, 3 Feb 2025 11:36:31 -0500 Subject: [PATCH] ease validation --- CHANGELOG.md | 6 ++++++ src/_incydr_sdk/agents/models.py | 7 ++++--- src/_incydr_sdk/audit_log/models.py | 5 +++-- src/_incydr_sdk/cases/models.py | 7 ++++--- src/_incydr_sdk/file_events/models/event.py | 3 ++- src/_incydr_sdk/queries/file_events.py | 2 +- src/_incydr_sdk/trusted_activities/models.py | 13 +++++++------ src/_incydr_sdk/watchlists/models/requests.py | 3 ++- src/_incydr_sdk/watchlists/models/responses.py | 3 ++- 9 files changed, 31 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8c01685..bc5ca991 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,12 @@ how a consumer would use the library or CLI tool (e.g. adding unit tests, updating documentation, etc) are not captured here. +## Unreleased + +### Fixed + +- A bug where in some rare cases searching file events could cause the SDK to throw a validation error on the server's correct response. + ## 2.2.2 - 2025-01-08 ### Fixed diff --git a/src/_incydr_sdk/agents/models.py b/src/_incydr_sdk/agents/models.py index 6c90b6fa..313d5fe9 100644 --- a/src/_incydr_sdk/agents/models.py +++ b/src/_incydr_sdk/agents/models.py @@ -3,6 +3,7 @@ from datetime import datetime from typing import List from typing import Optional +from typing import Union from pydantic import BaseModel from pydantic import Field @@ -63,7 +64,7 @@ class Agent(ResponseModel): machine_id: Optional[str] = Field(alias="machineId") serial_number: Optional[str] = Field(alias="serialNumber") active: Optional[bool] - agent_type: Optional[AgentType] = Field(alias="agentType") + agent_type: Optional[Union[AgentType, str]] = Field(alias="agentType") agent_health_issue_types: Optional[List[str]] = Field(alias="agentHealthIssueTypes") app_version: Optional[str] = Field(alias="appVersion") product_version: Optional[str] = Field(alias="productVersion") @@ -98,10 +99,10 @@ class AgentUpdateRequest(BaseModel): class QueryAgentsRequest(BaseModel): active: Optional[bool] - agentType: Optional[AgentType] + agentType: Optional[Union[AgentType, str]] agentHealthy: Optional[bool] anyOfAgentHealthIssueTypes: Optional[List[str]] - srtKey: Optional[SortKeys] + srtKey: Optional[Union[SortKeys, str]] srtDir: Optional[str] pageSize: Optional[int] page: Optional[int] diff --git a/src/_incydr_sdk/audit_log/models.py b/src/_incydr_sdk/audit_log/models.py index 73833f6c..0e907d69 100644 --- a/src/_incydr_sdk/audit_log/models.py +++ b/src/_incydr_sdk/audit_log/models.py @@ -5,6 +5,7 @@ from typing import Dict from typing import List from typing import Optional +from typing import Union from pydantic import BaseModel from pydantic import Field @@ -63,7 +64,7 @@ class QueryExportRequest(Model): dateRange: Optional[DateRange] eventTypes: Optional[List[str]] resourceIds: Optional[List[str]] - userTypes: Optional[List[UserTypes]] + userTypes: Optional[List[Union[UserTypes, str]]] class QueryAuditLogRequest(Model): @@ -75,4 +76,4 @@ class QueryAuditLogRequest(Model): page: int pageSize: int resourceIds: Optional[List[str]] - userTypes: Optional[List[UserTypes]] + userTypes: Optional[List[Union[UserTypes, str]]] diff --git a/src/_incydr_sdk/cases/models.py b/src/_incydr_sdk/cases/models.py index 4d67f60b..030fdb62 100644 --- a/src/_incydr_sdk/cases/models.py +++ b/src/_incydr_sdk/cases/models.py @@ -3,6 +3,7 @@ from datetime import datetime from typing import List from typing import Optional +from typing import Union from pydantic import BaseModel from pydantic import Extra @@ -48,7 +49,7 @@ class Case(ResponseModel, validate_assignment=True): updated_at: Optional[datetime] = Field(allow_mutation=False, alias="updatedAt") subject: Optional[str] subject_username: Optional[str] = Field(alias="subjectUsername") - status: CaseStatus + status: Union[CaseStatus, str] assignee: Optional[str] assignee_username: Optional[str] = Field( allow_mutation=False, alias="assigneeUsername" @@ -152,7 +153,7 @@ class FileEvent(Model): description="Lists indicators that the data may be exposed.", example=["OutsideTrustedDomains", "IsPublic"], ) - file_availability: Optional[FileAvailability] = Field( + file_availability: Optional[Union[FileAvailability, str]] = Field( None, alias="fileAvailability", description="The download availability status of the file associated with the event.", @@ -170,7 +171,7 @@ class FileEvent(Model): description="The file location on the user's device; a path forward or backslash should be included at the end of the filepath. Possibly null if the file event occurred on a cloud provider.", example="/Users/casey/Documents/", ) - risk_indicators: Optional[List[RiskIndicator]] = Field( + risk_indicators: Optional[List[Union[RiskIndicator, str]]] = Field( None, alias="riskIndicators", description="List of risk indicators identified for this event. If more than one risk indicator applies to this event, the sum of all indicators determines the total risk score.", diff --git a/src/_incydr_sdk/file_events/models/event.py b/src/_incydr_sdk/file_events/models/event.py index 92af44d3..e6f2b02a 100644 --- a/src/_incydr_sdk/file_events/models/event.py +++ b/src/_incydr_sdk/file_events/models/event.py @@ -1,6 +1,7 @@ from datetime import datetime from typing import List from typing import Optional +from typing import Union from pydantic import Field @@ -226,7 +227,7 @@ class Report(Model): description="The display name of the report.", example="Top Accounts Report", ) - type: Optional[ReportType] = Field( + type: Optional[Union[ReportType, str]] = Field( description='Indicates if the report is "REPORT_TYPE_AD_HOC" or "REPORT_TYPE_SAVED".', example="REPORT_TYPE_SAVED", ) diff --git a/src/_incydr_sdk/queries/file_events.py b/src/_incydr_sdk/queries/file_events.py index e789c7dd..8676d085 100644 --- a/src/_incydr_sdk/queries/file_events.py +++ b/src/_incydr_sdk/queries/file_events.py @@ -41,7 +41,7 @@ class Filter(BaseModel): term: str - operator: Operator + operator: Union[Operator, str] value: Optional[Union[int, str]] class Config: diff --git a/src/_incydr_sdk/trusted_activities/models.py b/src/_incydr_sdk/trusted_activities/models.py index fc35b785..27c00c43 100644 --- a/src/_incydr_sdk/trusted_activities/models.py +++ b/src/_incydr_sdk/trusted_activities/models.py @@ -3,6 +3,7 @@ from datetime import datetime from typing import List from typing import Optional +from typing import Union from pydantic import Extra from pydantic import Field @@ -15,7 +16,7 @@ class ProviderObject(Model): - name: Optional[Name] = Field( + name: Optional[Union[Name, str]] = Field( None, description="The name of a provider for a specified activity action.\n ### Supported providers for trusted " "activity type and actions\n\n - `DOMAIN`\n - `CLOUD_SHARE`\n - `BOX`\n - " @@ -26,7 +27,7 @@ class ProviderObject(Model): class ActivityAction(Model): - type: Optional[ActivityType] = Field( + type: Optional[Union[ActivityType, str]] = Field( None, description="The type of an activity action.\n### Supported trusted activity types for each activity action " "type\n\n- `CLOUD_SHARE` \n - `DOMAIN`\n- `CLOUD_SYNC` \n - `DOMAIN`\n - `ACCOUNT_NAME`\n- " @@ -40,7 +41,7 @@ class ActivityAction(Model): class ActivityActionGroup(Model): - name: Optional[Name] = Field( + name: Optional[Union[Name, str]] = Field( Name.DEFAULT, description="The name of the activity action group. Currently, only `DEFAULT` activity action group is " "supported.", @@ -85,10 +86,10 @@ class TrustedActivity(ResponseModel, validate_assignment=True): description: Optional[str] = Field( None, description="A description of the trusted activity." ) - principal_type: Optional[PrincipalType] = Field( + principal_type: Optional[Union[PrincipalType, str]] = Field( None, alias="principalType", allow_mutation=False ) - type: Optional[ActivityType] = Field( + type: Optional[Union[ActivityType, str]] = Field( None, description="The type of the trusted activity.", alias="type" ) update_time: Optional[datetime] = Field( @@ -129,7 +130,7 @@ class UpdateTrustedActivity(Model, extra=Extra.ignore): description="Whether the trusted activity represents a high value source", alias="isHighValueSource", ) - type: Optional[ActivityType] = Field( + type: Optional[Union[ActivityType, str]] = Field( None, description="The type of the trusted activity.\n\nNote: The `ACCOUNT_NAME` trusted activity type requires " "agent version 1.5.0 or later for Incydr \nProfessional, Enterprise, Gov F2, and Horizon product " diff --git a/src/_incydr_sdk/watchlists/models/requests.py b/src/_incydr_sdk/watchlists/models/requests.py index 0c33d0c6..6f48ff76 100644 --- a/src/_incydr_sdk/watchlists/models/requests.py +++ b/src/_incydr_sdk/watchlists/models/requests.py @@ -1,5 +1,6 @@ from typing import List from typing import Optional +from typing import Union from pydantic import BaseModel from pydantic import constr @@ -50,7 +51,7 @@ class CreateWatchlistRequest(BaseModel): description="The required title for a custom watchlist.", example="My Custom List", ) - watchlistType: WatchlistType + watchlistType: Union[WatchlistType, str] class Config: use_enum_values = True diff --git a/src/_incydr_sdk/watchlists/models/responses.py b/src/_incydr_sdk/watchlists/models/responses.py index 40a06379..a19c3028 100644 --- a/src/_incydr_sdk/watchlists/models/responses.py +++ b/src/_incydr_sdk/watchlists/models/responses.py @@ -3,6 +3,7 @@ from datetime import datetime from typing import List from typing import Optional +from typing import Union from pydantic import Field @@ -242,7 +243,7 @@ class Watchlist(ResponseModel): description: Optional[str] = Field( None, description="Description for a custom watchlist." ) - list_type: WatchlistType = Field(alias="listType") + list_type: Union[WatchlistType, str] = Field(alias="listType") stats: Optional[WatchlistStats] = None tenant_id: Optional[str] = Field( None, description="A unique tenant ID.", alias="tenantId"