Added all the endpoints

Get requests should work for all but the completion certificate
Post requests still need work
This commit is contained in:
Peter Annabel 2025-07-24 15:40:39 -05:00
parent 854f16cc45
commit 146431e818
44 changed files with 2712 additions and 105 deletions

View File

@ -92,7 +92,7 @@ agents = siem_api_client.agents.get()
### Managed SAT ###
# sends GET request to /company/companies/{id} endpoint
company = sat_api_client.company.companies.id(250).get()
accounts = sat_api_client.accounts.id("abc123").get()
### SIEM ###

View File

@ -37,15 +37,16 @@ class HuntressClient(ABC):
def _get_url(self) -> str:
pass
def _make_request( # noqa: C901
def _make_request(
self,
method: RequestMethod,
url: str,
data: RequestData | None = None,
rawdata: RequestData | None = None,
params: RequestParams | None = None,
headers: dict[str, str] | None = None,
retry_count: int = 0,
stream: bool = False, # noqa: FBT001, FBT002
stream: bool = False,
) -> Response:
"""
Make an API request using the specified method, endpoint, data, and parameters.
@ -79,6 +80,15 @@ class HuntressClient(ABC):
params=cast(dict[str, Any], params or {}),
stream=stream,
)
elif rawdata:
response = requests.request(
method,
url,
headers=headers,
data=rawdata,
params=cast(dict[str, Any], params or {}),
stream=stream,
)
else:
response = requests.request(
method,

View File

@ -1,22 +1,21 @@
import base64
import typing
from datetime import datetime, timedelta, timezone
from pyhuntress.clients.huntress_client import HuntressClient
from pyhuntress.config import Config
if typing.TYPE_CHECKING:
from pyhuntress.endpoints.managedsat.CompanyEndpoint import CompanyEndpoint
from pyhuntress.endpoints.managedsat.ConfigurationsEndpoint import ConfigurationsEndpoint
from pyhuntress.endpoints.managedsat.ExpenseEndpoint import ExpenseEndpoint
from pyhuntress.endpoints.managedsat.FinanceEndpoint import FinanceEndpoint
from pyhuntress.endpoints.managedsat.MarketingEndpoint import MarketingEndpoint
from pyhuntress.endpoints.managedsat.ProcurementEndpoint import ProcurementEndpoint
from pyhuntress.endpoints.managedsat.ProjectEndpoint import ProjectEndpoint
from pyhuntress.endpoints.managedsat.SalesEndpoint import SalesEndpoint
from pyhuntress.endpoints.managedsat.ScheduleEndpoint import ScheduleEndpoint
from pyhuntress.endpoints.managedsat.ServiceEndpoint import ServiceEndpoint
from pyhuntress.endpoints.managedsat.SystemEndpoint import SystemEndpoint
from pyhuntress.endpoints.managedsat.TimeEndpoint import TimeEndpoint
from pyhuntress.endpoints.managedsat.AccountsEndpoint import AccountsEndpoint
from pyhuntress.endpoints.managedsat.UsersEndpoint import UsersEndpoint
from pyhuntress.endpoints.managedsat.AssignmentsEndpoint import AssignmentsEndpoint
from pyhuntress.endpoints.managedsat.EpisodesEndpoint import EpisodesEndpoint
from pyhuntress.endpoints.managedsat.DepartmentsEndpoint import DepartmentsEndpoint
from pyhuntress.endpoints.managedsat.GroupsEndpoint import GroupsEndpoint
from pyhuntress.endpoints.managedsat.LearnersEndpoint import LearnersEndpoint
from pyhuntress.endpoints.managedsat.PhishingCampaignsEndpoint import PhishingCampaignsEndpoint
from pyhuntress.endpoints.managedsat.PhishingCampaignScenariosEndpoint import PhishingCampaignScenariosEndpoint
from pyhuntress.endpoints.managedsat.PhishingAttemptsEndpoint import PhishingAttemptsActionsEndpoint
from pyhuntress.endpoints.managedsat.PhishingScenariosEndpoint import PhishingScenariosEndpoint
class ManagedSATCodebaseError(Exception):
@ -32,134 +31,130 @@ class HuntressSATAPIClient(HuntressClient):
def __init__(
self,
managedsat_url: str,
public_key: str,
private_key: str,
client_id: str,
client_secret: str,
api_scopes: str,
) -> None:
"""
Initializes the client with the given credentials and optionally a specific codebase.
If no codebase is given, it tries to get it from the API.
Initializes the client with the given credentials.
Parameters:
managedsat_url (str): URL of the Huntress Managed SAT instance.
public_key (str): Your Huntress Managed SAT API Public key.
private_key (str): Your Huntress Managed SAT API Private key.
client_id (str): URL of the Huntress Managed SAT client id.
client_secret (str): Your Huntress Managed SAT API client secret.
api_scopes (str): Your Huntress Managed SAT API scope.
"""
self.managedsat_url: str = managedsat_url
self.public_key: str = public_key
self.private_key: str = private_key
self.client_id: str = client_id
self.client_secret: str = client_secret
self.api_scopes: str = api_scopes
self.token_expiry_time: datetime = datetime.now(tz=timezone.utc)
# Grab first access token
self.access_token: str = self._get_access_token()
# Initializing endpoints
@property
def company(self) -> "CompanyEndpoint":
from pyhuntress.endpoints.managedsat.CompanyEndpoint import CompanyEndpoint
def accounts(self) -> "AccountsEndpoint":
from pyhuntress.endpoints.managedsat.AccountsEndpoint import AccountsEndpoint
return CompanyEndpoint(self)
return AccountsEndpoint(self)
@property
def configurations(self) -> "ConfigurationsEndpoint":
from pyhuntress.endpoints.managedsat.ConfigurationsEndpoint import ConfigurationsEndpoint
def users(self) -> "UsersEndpoint":
from pyhuntress.endpoints.managedsat.UsersEndpoint import UsersEndpoint
return ConfigurationsEndpoint(self)
return UsersEndpoint(self)
@property
def expense(self) -> "ExpenseEndpoint":
from pyhuntress.endpoints.managedsat.ExpenseEndpoint import ExpenseEndpoint
def assignments(self) -> "AssignmentsEndpoint":
from pyhuntress.endpoints.managedsat.AssignmentsEndpoint import AssignmentsEndpoint
return ExpenseEndpoint(self)
return AssignmentsEndpoint(self)
@property
def finance(self) -> "FinanceEndpoint":
from pyhuntress.endpoints.managedsat.FinanceEndpoint import FinanceEndpoint
def episodes(self) -> "EpisodesEndpoint":
from pyhuntress.endpoints.managedsat.EpisodesEndpoint import EpisodesEndpoint
return FinanceEndpoint(self)
return EpisodesEndpoint(self)
@property
def marketing(self) -> "MarketingEndpoint":
from pyhuntress.endpoints.managedsat.MarketingEndpoint import MarketingEndpoint
def departments(self) -> "DepartmentsEndpoint":
from pyhuntress.endpoints.managedsat.DepartmentsEndpoint import DepartmentsEndpoint
return MarketingEndpoint(self)
return DepartmentsEndpoint(self)
@property
def procurement(self) -> "ProcurementEndpoint":
from pyhuntress.endpoints.managedsat.ProcurementEndpoint import ProcurementEndpoint
def groups(self) -> "GroupsEndpoint":
from pyhuntress.endpoints.managedsat.GroupsEndpoint import GroupsEndpoint
return ProcurementEndpoint(self)
return GroupsEndpoint(self)
@property
def project(self) -> "ProjectEndpoint":
from pyhuntress.endpoints.managedsat.ProjectEndpoint import ProjectEndpoint
def learners(self) -> "LearnersEndpoint":
from pyhuntress.endpoints.managedsat.LearnersEndpoint import LearnersEndpoint
return ProjectEndpoint(self)
return LearnersEndpoint(self)
@property
def sales(self) -> "SalesEndpoint":
from pyhuntress.endpoints.managedsat.SalesEndpoint import SalesEndpoint
def phishing_campaigns(self) -> "PhishingCampaignsEndpoint":
from pyhuntress.endpoints.managedsat.PhishingCampaignsEndpoint import PhishingCampaignsEndpoint
return SalesEndpoint(self)
return PhishingCampaignsEndpoint(self)
@property
def schedule(self) -> "ScheduleEndpoint":
from pyhuntress.endpoints.managedsat.ScheduleEndpoint import ScheduleEndpoint
def phishing_campaign_scenarios(self) -> "PhishingCampaignScenariosEndpoint":
from pyhuntress.endpoints.managedsat.PhishingCampaignScenariosEndpoint import PhishingCampaignScenariosEndpoint
return ScheduleEndpoint(self)
return PhishingCampaignScenariosEndpoint(self)
@property
def service(self) -> "ServiceEndpoint":
from pyhuntress.endpoints.managedsat.ServiceEndpoint import ServiceEndpoint
def phishing_attempts(self) -> "PhishingAttemptsActionsEndpoint":
from pyhuntress.endpoints.managedsat.PhishingAttemptsActionsEndpoint import PhishingAttemptsActionsEndpoint
return ServiceEndpoint(self)
return PhishingAttemptsActionsEndpoint(self)
@property
def system(self) -> "SystemEndpoint":
from pyhuntress.endpoints.managedsat.SystemEndpoint import SystemEndpoint
def phishing_scenarios(self) -> "PhishingScenariosEndpoint":
from pyhuntress.endpoints.managedsat.PhishingScenariosEndpoint import PhishingScenariosEndpoint
return SystemEndpoint(self)
@property
def time(self) -> "TimeEndpoint":
from pyhuntress.endpoints.managedsat.TimeEndpoint import TimeEndpoint
return TimeEndpoint(self)
return PhishingScenariosEndpoint(self)
def _get_url(self) -> str:
"""
Generates and returns the URL for the Huntress Managed SAT API endpoints based on the company url and codebase.
This only still exists incase Huntress eventually moves to some client specific URL format
Returns:
str: API URL.
"""
return f"https://{self.managedsat_url}/{self.codebase.strip('/')}/apis/3.0"
return f"https://mycurricula.com/api/v1"
def _try_get_codebase_from_api(self, managedsat_url: str, company_name: str, headers: dict[str, str]) -> str:
def _get_access_token(self) -> str:
"""
Tries to retrieve the codebase from the API using the provided company url, company name and headers.
Parameters:
company_url (str): URL of the company.
company_name (str): Name of the company.
headers (dict[str, str]): Headers to be sent in the request.
Returns:
str: Codebase string or None if an error occurs.
Performs a request to the ConnectWise Automate API to obtain an access token.
"""
url = f"https://{managedsat_url}/login/companyinfo/{company_name}"
response = self._make_request("GET", url, headers=headers)
return response.json().get("Codebase")
token_url = self._get_url().replace("api/v1", "oauth/token") #strip the API endpoints to use the oauth token url
auth_response = self._make_request(
"POST",
token_url,
rawdata={
"grant_type": "client_credentials",
"client_id": self.client_id,
"client_secret": self.client_secret,
"scope": self.api_scopes
},
headers={
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "application/json"
},
)
auth_resp_json = auth_response.json()
token = auth_resp_json["access_token"]
expires_in_sec = auth_resp_json["expires_in"]
self.token_expiry_time = datetime.now(tz=timezone.utc) + timedelta(seconds=expires_in_sec)
return token
def _get_auth_string(self) -> str:
"""
Creates and returns the base64 encoded authorization string required for API requests.
Returns:
str: Base64 encoded authorization string.
"""
return "Basic " + base64.b64encode(
bytes(
f"{self.company_name}+{self.public_key}:{self.private_key}",
encoding="utf8",
)
).decode("ascii")
def _refresh_access_token_if_necessary(self):
if datetime.now(tz=timezone.utc) > self.token_expiry_time:
self.access_token = self._get_access_token()
def _get_headers(self) -> dict[str, str]:
"""
@ -168,8 +163,9 @@ class HuntressSATAPIClient(HuntressClient):
Returns:
dict[str, str]: Dictionary of headers including Content-Type, Client ID, and Authorization.
"""
self._refresh_access_token_if_necessary()
return {
"Content-Type": "application/json",
"clientId": self.client_id,
"Authorization": self._get_auth_string(),
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
"Authorization": f"Bearer {self.access_token}",
}

View File

@ -0,0 +1,86 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.AccountsIdEndpoint import AccountsIdEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATAccounts
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AccountsEndpoint(
HuntressEndpoint,
IGettable[SATAccounts, HuntressSATRequestParams],
IPaginateable[SATAccounts, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "accounts", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATAccounts)
IPaginateable.__init__(self, SATAccounts)
def id(self, id: int) -> AccountsIdEndpoint:
"""
Sets the ID for this endpoint and returns an initialized AccountsIdEndpoint object to move down the chain.
Parameters:
id (int): The ID to set.
Returns:
AccountsIdEndpoint: The initialized AccountsIdEndpoint object.
"""
child = AccountsIdEndpoint(self.client, parent_endpoint=self)
child._id = id
return child
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATAccounts]:
"""
Performs a GET request against the /accounts endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATData]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATAccounts,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATAccounts:
"""
Performs a GET request against the /accounts endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATAccountInformation: The parsed response data.
"""
return self._parse_many(
SATAccounts,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,72 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATAssignments
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AccountsIdAssignmentsEndpoint(
HuntressEndpoint,
IGettable[SATAssignments, HuntressSATRequestParams],
IPaginateable[SATAssignments, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "assignments", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATAssignments)
IPaginateable.__init__(self, SATAssignments)
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATAssignments]:
"""
Performs a GET request against the /accounts/{id}/assignments endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATAssignments]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATAssignments,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATAssignments:
"""
Performs a GET request against the /accounts/{id}/assignments endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATAssignmentsInformation: The parsed response data.
"""
return self._parse_many(
SATAssignments,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,38 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
)
from pyhuntress.models.managedsat import SATDepartments
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AccountsIdDepartmentsEndpoint(
HuntressEndpoint,
IGettable[SATDepartments, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "departments", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATDepartments)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATDepartments:
"""
Performs a GET request against the /accounts/{id}/departments endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATDepartments: The parsed response data.
"""
return self._parse_many(
SATDepartments,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,56 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.AccountsIdUsersEndpoint import AccountsIdUsersEndpoint
from pyhuntress.endpoints.managedsat.AccountsIdAssignmentsEndpoint import AccountsIdAssignmentsEndpoint
from pyhuntress.endpoints.managedsat.AccountsIdDepartmentsEndpoint import AccountsIdDepartmentsEndpoint
from pyhuntress.endpoints.managedsat.AccountsIdGroupsEndpoint import AccountsIdGroupsEndpoint
from pyhuntress.endpoints.managedsat.AccountsIdLearnersEndpoint import AccountsIdLearnersEndpoint
from pyhuntress.endpoints.managedsat.AccountsIdPhishingCampaignsEndpoint import AccountsIdPhishingCampaignsEndpoint
from pyhuntress.endpoints.managedsat.AccountsIdPhishingScenariosEndpoint import AccountsIdPhishingScenariosEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATAccounts
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AccountsIdEndpoint(
HuntressEndpoint,
IGettable[SATAccounts, HuntressSATRequestParams],
IPaginateable[SATAccounts, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "{id}", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATAccounts)
IPaginateable.__init__(self, SATAccounts)
self.users = self._register_child_endpoint(AccountsIdUsersEndpoint(client, parent_endpoint=self))
self.assignments = self._register_child_endpoint(AccountsIdAssignmentsEndpoint(client, parent_endpoint=self))
self.departments = self._register_child_endpoint(AccountsIdDepartmentsEndpoint(client, parent_endpoint=self))
self.groups = self._register_child_endpoint(AccountsIdGroupsEndpoint(client, parent_endpoint=self))
self.learners = self._register_child_endpoint(AccountsIdLearnersEndpoint(client, parent_endpoint=self))
self.phishing_campaigns = self._register_child_endpoint(AccountsIdPhishingCampaignsEndpoint(client, parent_endpoint=self))
self.phishing_scenarios = self._register_child_endpoint(AccountsIdPhishingScenariosEndpoint(client, parent_endpoint=self))
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATAccounts:
"""
Performs a GET request against the /accounts/{id} endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATAccountsInformation: The parsed response data.
"""
return self._parse_one(
SATAccounts,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,40 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
)
from pyhuntress.models.managedsat import SATGroups
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AccountsIdGroupsEndpoint(
HuntressEndpoint,
IGettable[SATGroups, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "groups", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATGroups)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATGroups:
# TODO: Make this require the learnerid as a parameter
"""
Performs a GET request against the /accounts/{id}/groups endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATGroups: The parsed response data.
"""
return self._parse_many(
SATGroups,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,40 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
)
from pyhuntress.models.managedsat import SATLearners
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AccountsIdLearnersEndpoint(
HuntressEndpoint,
IGettable[SATLearners, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "learners", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATLearners)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATLearners:
# TODO: Make this require the learnerid as a parameter
"""
Performs a GET request against the /accounts/{id}/learners endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATGSATLearnersroups: The parsed response data.
"""
return self._parse_many(
SATLearners,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,38 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
)
from pyhuntress.models.managedsat import SATPhishingCampaigns
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AccountsIdPhishingCampaignsEndpoint(
HuntressEndpoint,
IGettable[SATPhishingCampaigns, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "phishing_campaigns", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATPhishingCampaigns)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATPhishingCampaigns:
"""
Performs a GET request against the /accounts/{id}/phishing-campaigns endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATPhishingCampaigns: The parsed response data.
"""
return self._parse_many(
SATPhishingCampaigns,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,38 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
)
from pyhuntress.models.managedsat import SATPhishingScenarios
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AccountsIdPhishingScenariosEndpoint(
HuntressEndpoint,
IGettable[SATPhishingScenarios, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "phishing_scenarios", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATPhishingScenarios)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATPhishingScenarios:
"""
Performs a GET request against the /accounts/{id}/phishing-scenarios endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATPhishingScenarios: The parsed response data.
"""
return self._parse_many(
SATPhishingScenarios,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,72 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATUsers
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AccountsIdUsersEndpoint(
HuntressEndpoint,
IGettable[SATUsers, HuntressSATRequestParams],
IPaginateable[SATUsers, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "users", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATUsers)
IPaginateable.__init__(self, SATUsers)
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATUsers]:
"""
Performs a GET request against the /accounts/{id}/users endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATUsers]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATUsers,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATUsers:
"""
Performs a GET request against the /accounts/{id}/users endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATUsersInformation: The parsed response data.
"""
return self._parse_many(
SATUsers,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,86 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.AssignmentsIdEndpoint import AssignmentsIdEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATAssignments
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AssignmentsEndpoint(
HuntressEndpoint,
IGettable[SATAssignments, HuntressSATRequestParams],
IPaginateable[SATAssignments, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "assignments", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATAssignments)
IPaginateable.__init__(self, SATAssignments)
def id(self, id: int) -> AssignmentsIdEndpoint:
"""
Sets the ID for this endpoint and returns an initialized AssignmentsIdEndpoint object to move down the chain.
Parameters:
id (int): The ID to set.
Returns:
AssignmentsIdEndpoint: The initialized AssignmentsIdEndpoint object.
"""
child = AssignmentsIdEndpoint(self.client, parent_endpoint=self)
child._id = id
return child
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATAssignments]:
"""
Performs a GET request against the /assignments endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATData]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATAssignments,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATAssignments:
"""
Performs a GET request against the /assignments endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATAssignments: The parsed response data.
"""
return self._parse_many(
SATAssignments,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,40 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
)
from pyhuntress.models.managedsat import SATAssignmentsCompletionCertificates
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AssignmentsIdCompletionCertificateEndpoint(
HuntressEndpoint,
IGettable[SATAssignmentsCompletionCertificates, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "completion-certificate", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATAssignmentsCompletionCertificates)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATAssignmentsCompletionCertificates:
# TODO: Make this require the learnerid as a parameter
"""
Performs a GET request against the /assignments/{id}/completion-certificate endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATAssignmentsCompletionCertificatesInformation: The parsed response data.
"""
return self._parse_one(
SATAssignmentsCompletionCertificates,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,83 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.AssignmentsIdLearnersEndpoint import AssignmentsIdLearnersEndpoint
from pyhuntress.endpoints.managedsat.AssignmentsIdLearnerActivityEndpoint import AssignmentsIdLearnerActivityEndpoint
from pyhuntress.endpoints.managedsat.AssignmentsIdCompletionCertificateEndpoint import AssignmentsIdCompletionCertificateEndpoint
from pyhuntress.endpoints.managedsat.AssignmentsIdEnrollmentConditionsEndpoint import AssignmentsIdEnrollmentConditionsEndpoint
from pyhuntress.endpoints.managedsat.AssignmentsIdEnrollmentExtrasEndpoint import AssignmentsIdEnrollmentExtrasEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATAssignments
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AssignmentsIdEndpoint(
HuntressEndpoint,
IGettable[SATAssignments, HuntressSATRequestParams],
IPaginateable[SATAssignments, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "{id}", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATAssignments)
IPaginateable.__init__(self, SATAssignments)
self.learners = self._register_child_endpoint(AssignmentsIdLearnersEndpoint(client, parent_endpoint=self))
self.learner_activity = self._register_child_endpoint(AssignmentsIdLearnerActivityEndpoint(client, parent_endpoint=self))
self.completion_certificate = self._register_child_endpoint(AssignmentsIdCompletionCertificateEndpoint(client, parent_endpoint=self))
self.enrollment_conditions = self._register_child_endpoint(AssignmentsIdEnrollmentConditionsEndpoint(client, parent_endpoint=self))
self.enrollment_extras = self._register_child_endpoint(AssignmentsIdEnrollmentExtrasEndpoint(client, parent_endpoint=self))
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATAssignments]:
"""
Performs a GET request against the /assignments/{id} endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATAssignments]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATAssignments,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATAssignments:
"""
Performs a GET request against the /assignments/{id} endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATAssignmentsInformation: The parsed response data.
"""
return self._parse_one(
SATAssignments,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,40 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
)
from pyhuntress.models.managedsat import SATAssignments
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AssignmentsIdEnrollmentConditionsEndpoint(
HuntressEndpoint,
IGettable[SATAssignments, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "enrollment-conditions", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATAssignments)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATAssignments:
# TODO: Make this require the learnerid as a parameter
"""
Performs a GET request against the /assignments/{id}/enrollment-conditions endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATAssignmentsInformation: The parsed response data.
"""
return self._parse_many(
SATAssignments,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,40 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
)
from pyhuntress.models.managedsat import SATAssignments
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AssignmentsIdEnrollmentExtrasEndpoint(
HuntressEndpoint,
IGettable[SATAssignments, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "enrollment-extras", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATAssignments)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATAssignments:
# TODO: Make this require the learnerid as a parameter
"""
Performs a GET request against the /assignments/{id}/enrollment-extras endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATAssignmentsInformation: The parsed response data.
"""
return self._parse_many(
SATAssignments,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,72 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATLearnerActivities
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AssignmentsIdLearnerActivityEndpoint(
HuntressEndpoint,
IGettable[SATLearnerActivities, HuntressSATRequestParams],
IPaginateable[SATLearnerActivities, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "learner-activity", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATLearnerActivities)
IPaginateable.__init__(self, SATLearnerActivities)
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATLearnerActivities]:
"""
Performs a GET request against the /assignments/{id}/learner-activity endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATLearnerActivities]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATLearnerActivities,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATLearnerActivities:
"""
Performs a GET request against the /assignments/{id}/learner-activity endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATLearnerActivitiesInformation: The parsed response data.
"""
return self._parse_many(
SATLearnerActivities,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,72 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATLearners
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class AssignmentsIdLearnersEndpoint(
HuntressEndpoint,
IGettable[SATLearners, HuntressSATRequestParams],
IPaginateable[SATLearners, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "learners", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATLearners)
IPaginateable.__init__(self, SATLearners)
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATLearners]:
"""
Performs a GET request against the /assignments/{id}/learners endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATLearners]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATLearners,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATLearners:
"""
Performs a GET request against the /assignments/{id}/learners endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATLearnersInformation: The parsed response data.
"""
return self._parse_many(
SATLearners,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,86 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.DepartmentsIdEndpoint import DepartmentsIdEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATDepartments
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class DepartmentsEndpoint(
HuntressEndpoint,
IGettable[SATDepartments, HuntressSATRequestParams],
IPaginateable[SATDepartments, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "departments", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATDepartments)
IPaginateable.__init__(self, SATDepartments)
def id(self, id: int) -> DepartmentsIdEndpoint:
"""
Sets the ID for this endpoint and returns an initialized DepartmentsIdEndpoint object to move down the chain.
Parameters:
id (int): The ID to set.
Returns:
DepartmentsIdEndpoint: The initialized DepartmentsIdEndpoint object.
"""
child = DepartmentsIdEndpoint(self.client, parent_endpoint=self)
child._id = id
return child
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATDepartments]:
"""
Performs a GET request against the /departments endpoitments endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATDepartments]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATDepartments,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATDepartments:
"""
Performs a GET request against the /departments endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATDepartments: The parsed response data.
"""
return self._parse_many(
SATDepartments,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,72 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATDepartments
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class DepartmentsIdEndpoint(
HuntressEndpoint,
IGettable[SATDepartments, HuntressSATRequestParams],
IPaginateable[SATDepartments, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "{id}", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATDepartments)
IPaginateable.__init__(self, SATDepartments)
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATDepartments]:
"""
Performs a GET request against the /departments/{id} endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATDepartments]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATDepartments,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATDepartments:
"""
Performs a GET request against the /departments/{id} endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATDepartments: The parsed response data.
"""
return self._parse_one(
SATDepartments,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,86 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.EpisodesIdEndpoint import EpisodesIdEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATEpisodes
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class EpisodesEndpoint(
HuntressEndpoint,
IGettable[SATEpisodes, HuntressSATRequestParams],
IPaginateable[SATEpisodes, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "episodes", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATEpisodes)
IPaginateable.__init__(self, SATEpisodes)
def id(self, id: int) -> EpisodesIdEndpoint:
"""
Sets the ID for this endpoint and returns an initialized EpisodesIdEndpoint object to move down the chain.
Parameters:
id (int): The ID to set.
Returns:
EpisodesIdEndpoint: The initialized EpisodesIdEndpoint object.
"""
child = EpisodesIdEndpoint(self.client, parent_endpoint=self)
child._id = id
return child
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATEpisodes]:
"""
Performs a GET request against the /episodes endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATData]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATEpisodes,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATEpisodes:
"""
Performs a GET request against the /episodes endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATEpisodes: The parsed response data.
"""
return self._parse_many(
SATEpisodes,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,72 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATEpisodes
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class EpisodesIdEndpoint(
HuntressEndpoint,
IGettable[SATEpisodes, HuntressSATRequestParams],
IPaginateable[SATEpisodes, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "{id}", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATEpisodes)
IPaginateable.__init__(self, SATEpisodes)
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATEpisodes]:
"""
Performs a GET request against the /episodes/{id} endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATEpisodes]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATEpisodes,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATEpisodes:
"""
Performs a GET request against the /episodes/{id} endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATEpisodes: The parsed response data.
"""
return self._parse_one(
SATEpisodes,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,86 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.GroupsIdEndpoint import GroupsIdEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATGroups
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class GroupsEndpoint(
HuntressEndpoint,
IGettable[SATGroups, HuntressSATRequestParams],
IPaginateable[SATGroups, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "groups", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATGroups)
IPaginateable.__init__(self, SATGroups)
def id(self, id: int) -> GroupsIdEndpoint:
"""
Sets the ID for this endpoint and returns an initialized GroupsIdEndpoint object to move down the chain.
Parameters:
id (int): The ID to set.
Returns:
GroupsIdEndpoint: The initialized GroupsIdEndpoint object.
"""
child = GroupsIdEndpoint(self.client, parent_endpoint=self)
child._id = id
return child
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATGroups]:
"""
Performs a GET request against the /groups endpoitments endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATGroups]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATGroups,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATGroups:
"""
Performs a GET request against the /groups endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATGroups: The parsed response data.
"""
return self._parse_many(
SATGroups,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,72 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATGroups
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class GroupsIdEndpoint(
HuntressEndpoint,
IGettable[SATGroups, HuntressSATRequestParams],
IPaginateable[SATGroups, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "{id}", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATGroups)
IPaginateable.__init__(self, SATGroups)
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATGroups]:
"""
Performs a GET request against the /groups/{id} endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATGroups]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATGroups,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATGroups:
"""
Performs a GET request against the /groups/{id} endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATGroups: The parsed response data.
"""
return self._parse_one(
SATGroups,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,86 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.LearnersIdEndpoint import LearnersIdEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATLearners
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class LearnersEndpoint(
HuntressEndpoint,
IGettable[SATLearners, HuntressSATRequestParams],
IPaginateable[SATLearners, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "learners", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATLearners)
IPaginateable.__init__(self, SATLearners)
def id(self, id: int) -> LearnersIdEndpoint:
"""
Sets the ID for this endpoint and returns an initialized LearnersIdEndpoint object to move down the chain.
Parameters:
id (int): The ID to set.
Returns:
LearnersIdEndpoint: The initialized LearnersIdEndpoint object.
"""
child = LearnersIdEndpoint(self.client, parent_endpoint=self)
child._id = id
return child
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATLearners]:
"""
Performs a GET request against the /learners endpoitments endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATLearners]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATLearners,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATLearners:
"""
Performs a GET request against the /learners endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATLearners: The parsed response data.
"""
return self._parse_many(
SATLearners,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,72 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATLearners
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class LearnersIdEndpoint(
HuntressEndpoint,
IGettable[SATLearners, HuntressSATRequestParams],
IPaginateable[SATLearners, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "{id}", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATLearners)
IPaginateable.__init__(self, SATLearners)
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATLearners]:
"""
Performs a GET request against the /learners/{id} endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATLearners]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATLearners,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATLearners:
"""
Performs a GET request against the /learners/{id} endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATLearners: The parsed response data.
"""
return self._parse_one(
SATLearners,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,21 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.PhishingAttemptsActionsReportEndpoint import PhishingAttemptsActionsReportEndpoint
from pyhuntress.interfaces import (
IPostable,
)
from pyhuntress.models.managedsat import SATPhishingAttemptsReport
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class PhishingAttemptsActionsEndpoint(
HuntressEndpoint,
IPostable[SATPhishingAttemptsReport, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "actions", parent_endpoint=parent_endpoint)
IPostable.__init__(self, SATPhishingAttemptsReport)
self.report = self._register_child_endpoint(PhishingAttemptsActionsReportEndpoint(client, parent_endpoint=self))

View File

@ -0,0 +1,30 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IPostable,
)
from pyhuntress.models.managedsat import SATPhishingAttemptsReport
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class PhishingAttemptsActionsReportEndpoint(
HuntressEndpoint,
IPostable[SATPhishingAttemptsReport, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "report", parent_endpoint=parent_endpoint)
IPostable.__init__(self, SATPhishingAttemptsReport)
# def post(self, data: JSON | None = None, params: HuntressSATRequestParams | None = None) -> SATUsers:
# """
# Performs a POST request against the /company/companies endpoint.
#
# Parameters:
# data (dict[str, Any]): The data to send in the request body.
# params (dict[str, int | str]): The parameters to send in the request query string.
# Returns:
# SATUsers: The parsed response data.
# """
# return self._parse_one(SATUsers, super()._make_request("POST", data=data, params=params).json())

View File

@ -0,0 +1,21 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.PhishingAttemptsActionsEndpoint import PhishingAttemptsActionsEndpoint
from pyhuntress.interfaces import (
IPostable,
)
from pyhuntress.models.managedsat import SATPhishingAttemptsReport
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class PhishingAttemptsActionsEndpoint(
HuntressEndpoint,
IPostable[SATPhishingAttemptsReport, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "phishing-attempts", parent_endpoint=parent_endpoint)
IPostable.__init__(self, SATPhishingAttemptsReport)
self.actions = self._register_child_endpoint(PhishingAttemptsActionsEndpoint(client, parent_endpoint=self))

View File

@ -0,0 +1,86 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.PhishingCampaignScenariosIdEndpoint import PhishingCampaignScenariosIdEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATPhishingScenarios
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class PhishingCampaignScenariosEndpoint(
HuntressEndpoint,
IGettable[SATPhishingScenarios, HuntressSATRequestParams],
IPaginateable[SATPhishingScenarios, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "phishing-campaign-scenarios", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATPhishingScenarios)
IPaginateable.__init__(self, SATPhishingScenarios)
def id(self, id: int) -> PhishingCampaignScenariosIdEndpoint:
"""
Sets the ID for this endpoint and returns an initialized PhishingCampaignScenariosIdEndpoint object to move down the chain.
Parameters:
id (int): The ID to set.
Returns:
PhishingCampaignScenariosIdEndpoint: The initialized PhishingCampaignScenariosIdEndpoint object.
"""
child = PhishingCampaignScenariosIdEndpoint(self.client, parent_endpoint=self)
child._id = id
return child
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATPhishingScenarios]:
"""
Performs a GET request against the /phishing-campaign-scenarios endpoints endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATData]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATPhishingScenarios,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATPhishingScenarios:
"""
Performs a GET request against the /phishing-campaign-scenarios endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATPhishingScenarios: The parsed response data.
"""
return self._parse_many(
SATPhishingScenarios,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,38 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
)
from pyhuntress.models.managedsat import SATPhishingCampaignAttempts
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class PhishingCampaignScenariosIdAttemptsEndpoint(
HuntressEndpoint,
IGettable[SATPhishingCampaignAttempts, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "attempts", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATPhishingCampaignAttempts)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATPhishingCampaignAttempts:
"""
Performs a GET request against the /accounts/{id}/attempts endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATPhishingCampaignAttempts: The parsed response data.
"""
return self._parse_many(
SATPhishingCampaignAttempts,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,38 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
)
from pyhuntress.models.managedsat import SATPhishingCampaigns
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class PhishingCampaignScenariosIdCampaignEndpoint(
HuntressEndpoint,
IGettable[SATPhishingCampaigns, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "campaign", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATPhishingCampaigns)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATPhishingCampaigns:
"""
Performs a GET request against the /phishing-campaign-scenarios/{id}/campaign endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATPhishingCampaigns: The parsed response data.
"""
return self._parse_one(
SATPhishingCampaigns,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,79 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.PhishingCampaignScenariosIdAttemptsEndpoint import PhishingCampaignScenariosIdAttemptsEndpoint
from pyhuntress.endpoints.managedsat.PhishingCampaignScenariosIdCampaignEndpoint import PhishingCampaignScenariosIdCampaignEndpoint
from pyhuntress.endpoints.managedsat.PhishingCampaignScenariosIdScenarioEndpoint import PhishingCampaignScenariosIdScenarioEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATPhishingScenarios
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class PhishingCampaignScenariosIdEndpoint(
HuntressEndpoint,
IGettable[SATPhishingScenarios, HuntressSATRequestParams],
IPaginateable[SATPhishingScenarios, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "{id}", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATPhishingScenarios)
IPaginateable.__init__(self, SATPhishingScenarios)
self.attempts = self._register_child_endpoint(PhishingCampaignScenariosIdAttemptsEndpoint(client, parent_endpoint=self))
self.campaign = self._register_child_endpoint(PhishingCampaignScenariosIdCampaignEndpoint(client, parent_endpoint=self))
self.campaign = self._register_child_endpoint(PhishingCampaignScenariosIdScenarioEndpoint(client, parent_endpoint=self))
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATPhishingScenarios]:
"""
Performs a GET request against the /phishing-campaigns/{id} endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATPhishingScenarios]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATPhishingScenarios,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATPhishingScenarios:
"""
Performs a GET request against the /phishing-campaigns/{id} endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATPhishingScenarios: The parsed response data.
"""
return self._parse_one(
SATPhishingScenarios,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,38 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
)
from pyhuntress.models.managedsat import SATPhishingScenarios
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class PhishingCampaignScenariosIdScenarioEndpoint(
HuntressEndpoint,
IGettable[SATPhishingScenarios, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "scenario", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATPhishingScenarios)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATPhishingScenarios:
"""
Performs a GET request against the /phishing-campaign-scenarios/{id}/scenario endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATPhishingScenarios: The parsed response data.
"""
return self._parse_one(
SATPhishingScenarios,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,86 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.PhishingCampaignsIdEndpoint import PhishingCampaignsIdEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATPhishingCampaigns
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class PhishingCampaignsEndpoint(
HuntressEndpoint,
IGettable[SATPhishingCampaigns, HuntressSATRequestParams],
IPaginateable[SATPhishingCampaigns, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "phishing-campaigns", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATPhishingCampaigns)
IPaginateable.__init__(self, SATPhishingCampaigns)
def id(self, id: int) -> PhishingCampaignsIdEndpoint:
"""
Sets the ID for this endpoint and returns an initialized PhishingCampaignsIdEndpoint object to move down the chain.
Parameters:
id (int): The ID to set.
Returns:
PhishingCampaignsIdEndpoint: The initialized PhishingCampaignsIdEndpoint object.
"""
child = PhishingCampaignsIdEndpoint(self.client, parent_endpoint=self)
child._id = id
return child
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATPhishingCampaigns]:
"""
Performs a GET request against the /phishing-campaign endpoints endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATData]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATPhishingCampaigns,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATPhishingCampaigns:
"""
Performs a GET request against the /phishing-campaigns endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATPhishingCampaigns: The parsed response data.
"""
return self._parse_many(
SATPhishingCampaigns,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,40 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
)
from pyhuntress.models.managedsat import SATPhishingCampaignAttempts
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class PhishingCampaignsIdAttemptsEndpoint(
HuntressEndpoint,
IGettable[SATPhishingCampaignAttempts, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "attempts", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATPhishingCampaignAttempts)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATPhishingCampaignAttempts:
# TODO: Make this require the learnerid as a parameter
"""
Performs a GET request against the /accounts/{id}/attempts endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATPhishingCampaignAttempts: The parsed response data.
"""
return self._parse_many(
SATPhishingCampaignAttempts,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,40 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
)
from pyhuntress.models.managedsat import SATPhishingCampaigns
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class PhishingCampaignsIdCampaignScenariosEndpoint(
HuntressEndpoint,
IGettable[SATPhishingCampaigns, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "campaign-scenarios", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATPhishingCampaigns)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATPhishingCampaigns:
# TODO: Make this require the learnerid as a parameter
"""
Performs a GET request against the /phishing-campaigns/{id}/campaign-scenarios endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATPhishingCampaigns: The parsed response data.
"""
return self._parse_many(
SATPhishingCampaigns,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,77 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.PhishingCampaignsIdAttemptsEndpoint import PhishingCampaignsIdAttemptsEndpoint
from pyhuntress.endpoints.managedsat.PhishingCampaignsIdCampaignScenariosEndpoint import PhishingCampaignsIdCampaignScenariosEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATPhishingCampaigns
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class PhishingCampaignsIdEndpoint(
HuntressEndpoint,
IGettable[SATPhishingCampaigns, HuntressSATRequestParams],
IPaginateable[SATPhishingCampaigns, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "{id}", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATPhishingCampaigns)
IPaginateable.__init__(self, SATPhishingCampaigns)
self.attempts = self._register_child_endpoint(PhishingCampaignsIdAttemptsEndpoint(client, parent_endpoint=self))
self.campaign_scenarios = self._register_child_endpoint(PhishingCampaignsIdCampaignScenariosEndpoint(client, parent_endpoint=self))
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATPhishingCampaigns]:
"""
Performs a GET request against the /phishing-campaigns/{id} endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATPhishingCampaigns]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATPhishingCampaigns,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATPhishingCampaigns:
"""
Performs a GET request against the /phishing-campaigns/{id} endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATPhishingCampaigns: The parsed response data.
"""
return self._parse_one(
SATPhishingCampaigns,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,86 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.PhishingScenariosIdEndpoint import PhishingScenariosIdEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATPhishingScenarios
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class PhishingScenariosEndpoint(
HuntressEndpoint,
IGettable[SATPhishingScenarios, HuntressSATRequestParams],
IPaginateable[SATPhishingScenarios, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "phishing-scenarios", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATPhishingScenarios)
IPaginateable.__init__(self, SATPhishingScenarios)
def id(self, id: int) -> PhishingScenariosIdEndpoint:
"""
Sets the ID for this endpoint and returns an initialized PhishingScenariosIdEndpoint object to move down the chain.
Parameters:
id (int): The ID to set.
Returns:
PhishingScenariosIdEndpoint: The initialized PhishingScenariosIdEndpoint object.
"""
child = PhishingScenariosIdEndpoint(self.client, parent_endpoint=self)
child._id = id
return child
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATPhishingScenarios]:
"""
Performs a GET request against the /phishing-scenarios endpoitments endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATPhishingScenarios]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATPhishingScenarios,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATPhishingScenarios:
"""
Performs a GET request against the /phishing-scenarios endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATGroups: The parsed response data.
"""
return self._parse_many(
SATPhishingScenarios,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,72 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATPhishingScenarios
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class PhishingScenariosIdEndpoint(
HuntressEndpoint,
IGettable[SATPhishingScenarios, HuntressSATRequestParams],
IPaginateable[SATPhishingScenarios, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "{id}", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATPhishingScenarios)
IPaginateable.__init__(self, SATPhishingScenarios)
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATPhishingScenarios]:
"""
Performs a GET request against the /phishing-scenarios/{id} endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATPhishingScenarios]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATPhishingScenarios,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATPhishingScenarios:
"""
Performs a GET request against the /phishing-scenarios/{id} endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATPhishingScenarios: The parsed response data.
"""
return self._parse_one(
SATPhishingScenarios,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -0,0 +1,100 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.UsersIdEndpoint import UsersIdEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
IPostable,
)
from pyhuntress.models.managedsat import SATUsers
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class UsersEndpoint(
HuntressEndpoint,
IGettable[SATUsers, HuntressSATRequestParams],
# IPostable[SATUsers, HuntressSATRequestParams],
IPaginateable[SATUsers, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "users", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATUsers)
IPaginateable.__init__(self, SATUsers)
def id(self, id: int) -> UsersIdEndpoint:
"""
Sets the ID for this endpoint and returns an initialized UsersIdEndpoint object to move down the chain.
Parameters:
id (int): The ID to set.
Returns:
UsersIdEndpoint: The initialized UsersIdEndpoint object.
"""
child = UsersIdEndpoint(self.client, parent_endpoint=self)
child._id = id
return child
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATUsers]:
"""
Performs a GET request against the /users endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATData]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATUsers,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATUsers:
"""
Performs a GET request against the /users endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATAccountInformation: The parsed response data.
"""
return self._parse_many(
SATUsers,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)
# def post(self, data: JSON | None = None, params: HuntressSATRequestParams | None = None) -> SATUsers:
# """
# Performs a POST request against the /company/companies endpoint.
#
# Parameters:
# data (dict[str, Any]): The data to send in the request body.
# params (dict[str, int | str]): The parameters to send in the request query string.
# Returns:
# SATUsers: The parsed response data.
# """
# return self._parse_one(SATUsers, super()._make_request("POST", data=data, params=params).json())

View File

@ -0,0 +1,73 @@
from pyhuntress.endpoints.base.huntress_endpoint import HuntressEndpoint
from pyhuntress.endpoints.managedsat.AccountsIdUsersEndpoint import AccountsIdUsersEndpoint
from pyhuntress.interfaces import (
IGettable,
IPaginateable,
)
from pyhuntress.models.managedsat import SATUsers
from pyhuntress.responses.paginated_response import PaginatedResponse
from pyhuntress.types import (
JSON,
HuntressSATRequestParams,
)
class UsersIdEndpoint(
HuntressEndpoint,
IGettable[SATUsers, HuntressSATRequestParams],
IPaginateable[SATUsers, HuntressSATRequestParams],
):
def __init__(self, client, parent_endpoint=None) -> None:
HuntressEndpoint.__init__(self, client, "{id}", parent_endpoint=parent_endpoint)
IGettable.__init__(self, SATUsers)
IPaginateable.__init__(self, SATUsers)
def paginated(
self,
page: int,
limit: int,
params: HuntressSATRequestParams | None = None,
) -> PaginatedResponse[SATUsers]:
"""
Performs a GET request against the /users/{id} endpoint and returns an initialized PaginatedResponse object.
Parameters:
page (int): The page number to request.
limit (int): The number of results to return per page.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
PaginatedResponse[SATUsers]: The initialized PaginatedResponse object.
"""
if params:
params["page"] = page
params["limit"] = limit
else:
params = {"page": page, "limit": limit}
return PaginatedResponse(
super()._make_request("GET", params=params),
SATUsers,
self,
"data",
page,
limit,
params,
)
def get(
self,
data: JSON | None = None,
params: HuntressSATRequestParams | None = None,
) -> SATUsers:
"""
Performs a GET request against the /users/{id} endpoint.
Parameters:
data (dict[str, Any]): The data to send in the request body.
params (dict[str, int | str]): The parameters to send in the request query string.
Returns:
SATUsersInformation: The parsed response data.
"""
return self._parse_one(
SATUsers,
super()._make_request("GET", data=data, params=params).json().get('data', {}),
)

View File

@ -6,13 +6,144 @@ from uuid import UUID
from pydantic import Field
from pyhuntress.models.base.huntress_model import HuntressModel
class SATData(HuntressModel):
type: Literal[
"accounts",
"users",
"assignments",
"learners",
"learner-activities",
] | None = Field(default=None, alias="Type")
id: str | None = Field(default=None, alias="Id")
attributes: dict[str, Any] | None = Field(default=None, alias="Attributes")
relationships: dict[str, dict[str, dict[str, str]]] | None = Field(default=None, alias="Relationships")
links: dict[str, str] | None = Field(default=None, alias="Links")
meta: dict[str, dict[str, int]] | None = Field(default=None, alias="Meta")
class SATAccounts(HuntressModel):
type: Literal[
"accounts",
] | None = Field(default=None, alias="Type")
id: str | None = Field(default=None, alias="Id")
attributes: dict[str, Any] | None = Field(default=None, alias="Attributes")
relationships: dict[str, dict[str, dict[str, str]]] | None = Field(default=None, alias="Relationships")
links: dict[str, str] | None = Field(default=None, alias="Links")
meta: dict[str, dict[str, int]] | None = Field(default=None, alias="Meta")
class SATUsers(HuntressModel):
type: Literal[
"users",
] | None = Field(default=None, alias="Type")
id: str | None = Field(default=None, alias="Id")
attributes: dict[str, Any] | None = Field(default=None, alias="Attributes")
relationships: dict[str, dict[str, dict[str, str]]] | None = Field(default=None, alias="Relationships")
links: dict[str, str] | None = Field(default=None, alias="Links")
meta: dict[str, dict[str, int]] | None = Field(default=None, alias="Meta")
class SATAssignments(HuntressModel):
type: Literal[
"assignments",
] | None = Field(default=None, alias="Type")
id: str | None = Field(default=None, alias="Id")
attributes: dict[str, Any] | None = Field(default=None, alias="Attributes")
relationships: dict[str, dict[str, dict[str, str]]] | None = Field(default=None, alias="Relationships")
links: dict[str, str] | None = Field(default=None, alias="Links")
meta: dict[str, dict[str, int]] | None = Field(default=None, alias="Meta")
class SATLearners(HuntressModel):
type: Literal[
"learners",
] | None = Field(default=None, alias="Type")
id: str | None = Field(default=None, alias="Id")
attributes: dict[str, Any] | None = Field(default=None, alias="Attributes")
relationships: dict[str, dict[str, dict[str, str]]] | None = Field(default=None, alias="Relationships")
links: dict[str, str] | None = Field(default=None, alias="Links")
meta: dict[str, dict[str, int]] | None = Field(default=None, alias="Meta")
class SATLearnerActivities(HuntressModel):
type: Literal[
"learner-activities",
] | None = Field(default=None, alias="Type")
id: str | None = Field(default=None, alias="Id")
attributes: dict[str, Any] | None = Field(default=None, alias="Attributes")
relationships: dict[str, dict[str, dict[str, str]]] | None = Field(default=None, alias="Relationships")
links: dict[str, str] | None = Field(default=None, alias="Links")
meta: dict[str, dict[str, int]] | None = Field(default=None, alias="Meta")
class SATAccountsAttributes(HuntressModel):
name: str | None = Field(default=None, alias="Name")
status: str | None = Field(default=None, alias="Status")
type: str | None = Field(default=None, alias="Type")
plan: str | None = Field(default=None, alias="Plan")
licenses: int | None = Field(default=None, alias="Licenses")
createdAt: datetime | None = Field(default=None, alias="CreatedAt")
updatedAt: datetime | None = Field(default=None, alias="UpdatedAt")
class SATAssignmentsCompletionCertificates(HuntressModel):
type: Any | None = Field(default=None, alias="Type")
attributes: dict[str, str] | None = Field(default=None, alias="Attributes")
#class AccountingBatch(HuntressModel):
# info: Annotated[dict[str, str] | None, Field(alias="_info")] = None
# batch_identifier: Annotated[str | None, Field(alias="batchIdentifier")] = None
# closed_flag: Annotated[bool | None, Field(alias="closedFlag")] = None
# export_expenses_flag: Annotated[bool | None, Field(alias="exportExpensesFlag")] = None
# export_invoices_flag: Annotated[bool | None, Field(alias="exportInvoicesFlag")] = None
# export_products_flag: Annotated[bool | None, Field(alias="exportProductsFlag")] = None
# id: int | None = None
class SATEpisodes(HuntressModel):
type: Literal[
"episodes",
] | None = Field(default=None, alias="Type")
id: str | None = Field(default=None, alias="Id")
attributes: dict[str, Any] | None = Field(default=None, alias="Attributes")
relationships: dict[str, dict[str, dict[str, str]]] | None = Field(default=None, alias="Relationships")
links: dict[str, str] | None = Field(default=None, alias="Links")
meta: dict[str, dict[str, int]] | None = Field(default=None, alias="Meta")
class SATDepartments(HuntressModel):
type: Literal[
"departments",
] | None = Field(default=None, alias="Type")
id: str | None = Field(default=None, alias="Id")
attributes: dict[str, Any] | None = Field(default=None, alias="Attributes")
relationships: dict[str, dict[str, dict[str, str]]] | None = Field(default=None, alias="Relationships")
links: dict[str, str] | None = Field(default=None, alias="Links")
meta: dict[str, dict[str, int]] | None = Field(default=None, alias="Meta")
class SATGroups(HuntressModel):
type: Literal[
"groups",
] | None = Field(default=None, alias="Type")
id: str | None = Field(default=None, alias="Id")
attributes: dict[str, Any] | None = Field(default=None, alias="Attributes")
relationships: dict[str, dict[str, dict[str, str]]] | None = Field(default=None, alias="Relationships")
links: dict[str, str] | None = Field(default=None, alias="Links")
meta: dict[str, dict[str, int]] | None = Field(default=None, alias="Meta")
class SATPhishingCampaigns(HuntressModel):
type: Literal[
"phishing-campaigns",
] | None = Field(default=None, alias="Type")
id: str | None = Field(default=None, alias="Id")
attributes: dict[str, Any] | None = Field(default=None, alias="Attributes")
relationships: dict[str, dict[str, dict[str, str]]] | None = Field(default=None, alias="Relationships")
links: dict[str, str] | None = Field(default=None, alias="Links")
meta: dict[str, dict[str, int]] | None = Field(default=None, alias="Meta")
class SATPhishingScenarios(HuntressModel):
type: Literal[
"phishing-campaign-scenarios",
] | None = Field(default=None, alias="Type")
id: str | None = Field(default=None, alias="Id")
attributes: dict[str, Any] | None = Field(default=None, alias="Attributes")
relationships: dict[str, dict[str, dict[str, str]]] | None = Field(default=None, alias="Relationships")
links: dict[str, str] | None = Field(default=None, alias="Links")
meta: dict[str, dict[str, int]] | None = Field(default=None, alias="Meta")
class SATPhishingCampaignAttempts(HuntressModel):
type: Literal[
"phishing-attempts",
] | None = Field(default=None, alias="Type")
id: str | None = Field(default=None, alias="Id")
attributes: dict[str, Any] | None = Field(default=None, alias="Attributes")
relationships: dict[str, dict[str, dict[str, str]]] | None = Field(default=None, alias="Relationships")
links: dict[str, str] | None = Field(default=None, alias="Links")
meta: dict[str, dict[str, int]] | None = Field(default=None, alias="Meta")
class SATPhishingAttemptsReport(HuntressModel):
data: Any
#This class needs to be researched more