pangea-sdk 1.4.0__tar.gz → 1.5.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/PKG-INFO +4 -3
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/README.md +2 -2
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/__init__.py +1 -1
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/deep_verify.py +2 -2
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/dump_audit.py +3 -9
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/exceptions.py +34 -5
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/request.py +40 -7
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/response.py +8 -0
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/__init__.py +1 -0
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/audit/audit.py +23 -2
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/audit/models.py +12 -0
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/audit/util.py +6 -1
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/intel.py +22 -22
- pangea_sdk-1.5.0/pangea/services/vault/models/asymmetric.py +67 -0
- pangea_sdk-1.5.0/pangea/services/vault/models/common.py +337 -0
- pangea_sdk-1.5.0/pangea/services/vault/models/secret.py +24 -0
- pangea_sdk-1.5.0/pangea/services/vault/models/symmetric.py +61 -0
- pangea_sdk-1.5.0/pangea/services/vault/vault.py +458 -0
- pangea_sdk-1.4.0/pangea/tools_util.py → pangea_sdk-1.5.0/pangea/tools.py +7 -9
- pangea_sdk-1.5.0/pangea/utils.py +22 -0
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pyproject.toml +2 -1
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/audit_logger.py +0 -0
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/config.py +0 -0
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/deprecated.py +0 -0
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/audit/exceptions.py +0 -0
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/audit/signing.py +0 -0
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/base.py +0 -0
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/embargo.py +0 -0
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/redact.py +0 -0
- {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/verify_audit.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: pangea-sdk
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.5.0
|
4
4
|
Summary: Pangea API SDK
|
5
5
|
License: MIT
|
6
6
|
Keywords: Pangea,SDK,Audit
|
@@ -19,6 +19,7 @@ Requires-Dist: alive-progress (>=2.4.1,<3.0.0)
|
|
19
19
|
Requires-Dist: cryptography (==39.0.1)
|
20
20
|
Requires-Dist: deprecated (>=1.2.13,<2.0.0)
|
21
21
|
Requires-Dist: pydantic (>=1.10.2,<2.0.0)
|
22
|
+
Requires-Dist: pytest (>=7.2.0,<8.0.0)
|
22
23
|
Requires-Dist: python-dateutil (>=2.8.2,<3.0.0)
|
23
24
|
Requires-Dist: requests (>=2.27.1,<3.0.0)
|
24
25
|
Requires-Dist: schema (>=0.7.5,<0.8.0)
|
@@ -27,7 +28,7 @@ Description-Content-Type: text/markdown
|
|
27
28
|
<p>
|
28
29
|
<br />
|
29
30
|
<a href="https://pangea.cloud?utm_source=github&utm_medium=node-sdk" target="_blank" rel="noopener noreferrer">
|
30
|
-
<img src="https://pangea-marketing.s3.us-west-2.amazonaws.com/pangea-color.svg" alt="Pangea Logo" height="40"
|
31
|
+
<img src="https://pangea-marketing.s3.us-west-2.amazonaws.com/pangea-color.svg" alt="Pangea Logo" height="40" />
|
31
32
|
</a>
|
32
33
|
<br />
|
33
34
|
</p>
|
@@ -36,7 +37,7 @@ Description-Content-Type: text/markdown
|
|
36
37
|
<br />
|
37
38
|
|
38
39
|
[![documentation](https://img.shields.io/badge/documentation-pangea-blue?style=for-the-badge&labelColor=551B76)](https://pangea.cloud/docs/sdk/python/)
|
39
|
-
[![
|
40
|
+
[![Slack](https://img.shields.io/badge/Slack-4A154B?style=for-the-badge&logo=slack&logoColor=white)](https://pangea.cloud/join-slack/)
|
40
41
|
|
41
42
|
<br />
|
42
43
|
</p>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<p>
|
2
2
|
<br />
|
3
3
|
<a href="https://pangea.cloud?utm_source=github&utm_medium=node-sdk" target="_blank" rel="noopener noreferrer">
|
4
|
-
<img src="https://pangea-marketing.s3.us-west-2.amazonaws.com/pangea-color.svg" alt="Pangea Logo" height="40"
|
4
|
+
<img src="https://pangea-marketing.s3.us-west-2.amazonaws.com/pangea-color.svg" alt="Pangea Logo" height="40" />
|
5
5
|
</a>
|
6
6
|
<br />
|
7
7
|
</p>
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<br />
|
11
11
|
|
12
12
|
[![documentation](https://img.shields.io/badge/documentation-pangea-blue?style=for-the-badge&labelColor=551B76)](https://pangea.cloud/docs/sdk/python/)
|
13
|
-
[![
|
13
|
+
[![Slack](https://img.shields.io/badge/Slack-4A154B?style=for-the-badge&logo=slack&logoColor=white)](https://pangea.cloud/join-slack/)
|
14
14
|
|
15
15
|
<br />
|
16
16
|
</p>
|
@@ -12,7 +12,7 @@ from itertools import groupby
|
|
12
12
|
import pangea.services.audit.util as audit_util
|
13
13
|
from pangea.services import Audit
|
14
14
|
from pangea.services.audit.models import EventEnvelope
|
15
|
-
from pangea.
|
15
|
+
from pangea.tools import Event, SequenceFollower, exit_with_error, file_events, init_audit, print_progress_bar
|
16
16
|
|
17
17
|
|
18
18
|
class Errors(t.TypedDict):
|
@@ -161,7 +161,7 @@ def deep_verify(audit: Audit, file: io.TextIOWrapper) -> Errors:
|
|
161
161
|
}
|
162
162
|
|
163
163
|
events = file_events(root_hashes, file)
|
164
|
-
events_by_idx: list[Event]
|
164
|
+
events_by_idx: t.Union[list[Event], t.Iterator[Event]]
|
165
165
|
cold_indexes = SequenceFollower()
|
166
166
|
for leaf_index, events_by_idx in groupby(events, lambda event: event.get("leaf_index")):
|
167
167
|
events_by_idx = list(events_by_idx)
|
@@ -11,21 +11,15 @@ from datetime import datetime
|
|
11
11
|
import dateutil.parser
|
12
12
|
from pangea.response import PangeaResponse
|
13
13
|
from pangea.services import Audit
|
14
|
-
from pangea.
|
15
|
-
|
16
|
-
get_script_name,
|
17
|
-
init_audit,
|
18
|
-
json_defaults,
|
19
|
-
make_aware_datetime,
|
20
|
-
print_progress_bar,
|
21
|
-
)
|
14
|
+
from pangea.tools import filter_deep_none, get_script_name, init_audit, make_aware_datetime, print_progress_bar
|
15
|
+
from pangea.utils import default_encoder
|
22
16
|
|
23
17
|
|
24
18
|
def dump_event(output: io.TextIOWrapper, row: dict, resp: PangeaResponse):
|
25
19
|
row_data = filter_deep_none(row.dict())
|
26
20
|
if resp.result.root:
|
27
21
|
row_data["tree_size"] = resp.result.root.size
|
28
|
-
output.write(json.dumps(row_data, default=
|
22
|
+
output.write(json.dumps(row_data, default=default_encoder) + "\n")
|
29
23
|
|
30
24
|
|
31
25
|
def dump_audit(audit: Audit, output: io.TextIOWrapper, start: datetime, end: datetime) -> int:
|
@@ -27,11 +27,18 @@ class PangeaAPIException(PangeaException):
|
|
27
27
|
def errors(self) -> List[ErrorField]:
|
28
28
|
return self.response.errors
|
29
29
|
|
30
|
+
def __repr__(self) -> str:
|
31
|
+
ret = f"Summary: {self.response.summary}\n"
|
32
|
+
if self.response.errors:
|
33
|
+
ret += "Errors: \n"
|
34
|
+
for ef in self.response.errors:
|
35
|
+
ret += f"\t {ef.detail}\n"
|
36
|
+
return ret
|
37
|
+
|
30
38
|
def __str__(self) -> str:
|
31
|
-
ret = "\n"
|
32
|
-
ret += f"Summary: {self.response.summary}\n"
|
39
|
+
ret = f"Summary: {self.response.summary}\n"
|
33
40
|
if self.response.errors:
|
34
|
-
ret += "Errors
|
41
|
+
ret += "Errors: \n"
|
35
42
|
for ef in self.response.errors:
|
36
43
|
ret += f"\t {ef.detail}\n"
|
37
44
|
return ret
|
@@ -85,8 +92,12 @@ class ProviderErrorException(PangeaAPIException):
|
|
85
92
|
"""Downstream provider error"""
|
86
93
|
|
87
94
|
|
88
|
-
class
|
89
|
-
"""A pangea
|
95
|
+
class InternalServerError(PangeaAPIException):
|
96
|
+
"""A pangea server error"""
|
97
|
+
|
98
|
+
def __init__(self, response: PangeaResponse):
|
99
|
+
message = f"summary: {response.summary}. request_id: {response.request_id}. request_time: {response.request_time}. response_time: ${response.response_time}"
|
100
|
+
super().__init__(message, response)
|
90
101
|
|
91
102
|
|
92
103
|
class ServiceNotAvailableException(PangeaAPIException):
|
@@ -112,3 +123,21 @@ class TreeNotFoundException(AuditAPIException):
|
|
112
123
|
|
113
124
|
class BadOffsetException(AuditAPIException):
|
114
125
|
"""Bad offset in results search"""
|
126
|
+
|
127
|
+
|
128
|
+
# Vault SDK specific exceptions
|
129
|
+
class VaultException(PangeaException):
|
130
|
+
"""Vault SDK specific exceptions"""
|
131
|
+
|
132
|
+
|
133
|
+
# Vault API specific exceptions
|
134
|
+
class VaultAPIException(PangeaAPIException):
|
135
|
+
"""Vault service specific exceptions"""
|
136
|
+
|
137
|
+
|
138
|
+
class ForbiddenVaultOperation(VaultAPIException):
|
139
|
+
"""Forbiden Vault operation"""
|
140
|
+
|
141
|
+
|
142
|
+
class VaultItemNotFound(VaultAPIException):
|
143
|
+
"""Vault item not found"""
|
@@ -4,13 +4,14 @@
|
|
4
4
|
import json
|
5
5
|
import logging
|
6
6
|
import time
|
7
|
-
from typing import
|
7
|
+
from typing import Dict, Union
|
8
8
|
|
9
9
|
import pangea
|
10
10
|
import requests
|
11
11
|
from pangea import exceptions
|
12
12
|
from pangea.config import PangeaConfig
|
13
13
|
from pangea.response import PangeaResponse, ResponseStatus
|
14
|
+
from pangea.utils import default_encoder
|
14
15
|
from requests.adapters import HTTPAdapter, Retry
|
15
16
|
|
16
17
|
|
@@ -76,7 +77,7 @@ class PangeaRequest(object):
|
|
76
77
|
|
77
78
|
return self._queued_retry_enabled
|
78
79
|
|
79
|
-
def post(self, endpoint: str = "", data:
|
80
|
+
def post(self, endpoint: str = "", data: Union[str, Dict] = {}) -> PangeaResponse:
|
80
81
|
"""Makes the POST call to a Pangea Service endpoint.
|
81
82
|
|
82
83
|
If queued_support mode is enabled, progress checks will be made for
|
@@ -92,14 +93,21 @@ class PangeaRequest(object):
|
|
92
93
|
various properties to retrieve individual fields
|
93
94
|
"""
|
94
95
|
url = self._url(endpoint)
|
95
|
-
data_send = json.dumps(data)
|
96
|
-
|
97
|
-
|
96
|
+
data_send = json.dumps(data, default=default_encoder) if isinstance(data, dict) else data
|
97
|
+
self.logger.debug(
|
98
|
+
json.dumps({"service": self.service, "action": "post", "url": url, "data": data}, default=default_encoder)
|
99
|
+
)
|
98
100
|
|
99
101
|
requests_response = self.session.post(url, headers=self._headers(), data=data_send)
|
100
102
|
|
101
103
|
if self._queued_retry_enabled and requests_response.status_code == 202:
|
102
104
|
response_json = requests_response.json()
|
105
|
+
self.logger.debug(
|
106
|
+
json.dumps(
|
107
|
+
{"service": self.service, "action": "post", "url": url, "response": response_json},
|
108
|
+
default=default_encoder,
|
109
|
+
)
|
110
|
+
)
|
103
111
|
request_id = response_json.get("request_id", None)
|
104
112
|
|
105
113
|
if not request_id:
|
@@ -109,6 +117,12 @@ class PangeaRequest(object):
|
|
109
117
|
else:
|
110
118
|
pangea_response = PangeaResponse(requests_response)
|
111
119
|
|
120
|
+
self.logger.debug(
|
121
|
+
json.dumps(
|
122
|
+
{"service": self.service, "action": "post", "url": url, "result": pangea_response.raw_result},
|
123
|
+
default=default_encoder,
|
124
|
+
)
|
125
|
+
)
|
112
126
|
self._check_response(pangea_response)
|
113
127
|
return pangea_response
|
114
128
|
|
@@ -126,9 +140,16 @@ class PangeaRequest(object):
|
|
126
140
|
url = self._url(f"{endpoint}/{path}")
|
127
141
|
|
128
142
|
self.logger.debug(json.dupms({"service": self.service, "action": "get", "url": url}))
|
129
|
-
|
130
143
|
requests_response = self.session.get(url, headers=self._headers())
|
144
|
+
|
131
145
|
pangea_response = PangeaResponse(requests_response)
|
146
|
+
|
147
|
+
self.logger.debug(
|
148
|
+
json.dumps(
|
149
|
+
{"service": self.service, "action": "post", "url": url, "result": pangea_response.raw_result},
|
150
|
+
default=default_encoder,
|
151
|
+
)
|
152
|
+
)
|
132
153
|
self._check_response(pangea_response)
|
133
154
|
return pangea_response
|
134
155
|
|
@@ -189,7 +210,13 @@ class PangeaRequest(object):
|
|
189
210
|
|
190
211
|
self.logger.error(
|
191
212
|
json.dumps(
|
192
|
-
{
|
213
|
+
{
|
214
|
+
"service": self.service,
|
215
|
+
"action": "api_error",
|
216
|
+
"url": response.raw_response.url,
|
217
|
+
"summary": summary,
|
218
|
+
"result": response.raw_result,
|
219
|
+
}
|
193
220
|
)
|
194
221
|
)
|
195
222
|
|
@@ -215,6 +242,12 @@ class PangeaRequest(object):
|
|
215
242
|
raise exceptions.IPNotFoundException(summary)
|
216
243
|
elif status == ResponseStatus.BAD_OFFSET.value:
|
217
244
|
raise exceptions.BadOffsetException(summary, response)
|
245
|
+
elif status == ResponseStatus.FORBIDDEN_VAULT_OPERATION.value:
|
246
|
+
raise exceptions.ForbiddenVaultOperation(summary, response)
|
247
|
+
elif status == ResponseStatus.VAULT_ITEM_NOT_FOUND.value:
|
248
|
+
raise exceptions.VaultItemNotFound(summary, response)
|
218
249
|
elif status == ResponseStatus.NOT_FOUND.value:
|
219
250
|
raise exceptions.NotFound(response.raw_response.url if response.raw_response is not None else "", response)
|
251
|
+
elif status == ResponseStatus.INTERNAL_SERVER_ERROR.value:
|
252
|
+
raise exceptions.InternalServerError(response)
|
220
253
|
raise exceptions.PangeaAPIException(f"{summary} ", response)
|
@@ -1,9 +1,11 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
import datetime
|
3
4
|
import enum
|
4
5
|
from typing import Any, Dict, Generic, List, Optional, TypeVar
|
5
6
|
|
6
7
|
import requests
|
8
|
+
from pangea.utils import format_datetime
|
7
9
|
from pydantic import BaseModel
|
8
10
|
|
9
11
|
T = TypeVar("T")
|
@@ -21,6 +23,9 @@ class APIResponseModel(BaseModel):
|
|
21
23
|
class APIRequestModel(BaseModel):
|
22
24
|
class Config:
|
23
25
|
arbitrary_types_allowed = True
|
26
|
+
json_encoders = {
|
27
|
+
datetime.datetime: format_datetime,
|
28
|
+
}
|
24
29
|
|
25
30
|
|
26
31
|
class PangeaResponseResult(APIResponseModel):
|
@@ -63,7 +68,10 @@ class ResponseStatus(str, enum.Enum):
|
|
63
68
|
TREE_NOT_FOUND = "TreeNotFound"
|
64
69
|
IP_NOT_FOUND = "IPNotFound"
|
65
70
|
BAD_OFFSET = "BadOffset"
|
71
|
+
FORBIDDEN_VAULT_OPERATION = "ForbiddenVaultOperation"
|
72
|
+
VAULT_ITEM_NOT_FOUND = "VaultItemNotFound"
|
66
73
|
NOT_FOUND = "NotFound"
|
74
|
+
INTERNAL_SERVER_ERROR = "InternalError"
|
67
75
|
|
68
76
|
|
69
77
|
class ResponseHeader(APIResponseModel):
|
@@ -1,10 +1,30 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
import datetime
|
3
4
|
from typing import Dict, Optional, Union
|
4
5
|
|
5
6
|
from pangea.response import PangeaResponse
|
6
7
|
from pangea.services.audit.exceptions import AuditException, EventCorruption
|
7
|
-
from pangea.services.audit.models import
|
8
|
+
from pangea.services.audit.models import (
|
9
|
+
Event,
|
10
|
+
EventEnvelope,
|
11
|
+
EventSigning,
|
12
|
+
EventVerification,
|
13
|
+
LogRequest,
|
14
|
+
LogResult,
|
15
|
+
PublishedRoot,
|
16
|
+
Root,
|
17
|
+
RootRequest,
|
18
|
+
RootResult,
|
19
|
+
RootSource,
|
20
|
+
SearchEvent,
|
21
|
+
SearchOrder,
|
22
|
+
SearchOrderBy,
|
23
|
+
SearchOutput,
|
24
|
+
SearchRequest,
|
25
|
+
SearchResultOutput,
|
26
|
+
SearchResultRequest,
|
27
|
+
)
|
8
28
|
from pangea.services.audit.signing import Signer, Verifier
|
9
29
|
from pangea.services.audit.util import (
|
10
30
|
b64encode_ascii,
|
@@ -99,6 +119,7 @@ class Audit(ServiceBase):
|
|
99
119
|
verify (bool, optional): True to verify logs consistency after response.
|
100
120
|
signing (bool, optional): True to sign event.
|
101
121
|
verbose (bool, optional): True to get a more verbose response.
|
122
|
+
tenant_id (string, optional): Used to record the tenant associated with this activity.
|
102
123
|
Raises:
|
103
124
|
AuditException: If an audit based api exception happens
|
104
125
|
PangeaAPIException: If an API Error happens
|
@@ -169,7 +190,7 @@ class Audit(ServiceBase):
|
|
169
190
|
# verify event hash
|
170
191
|
if response.result.hash and not verify_envelope_hash(response.result.envelope, response.result.hash):
|
171
192
|
# it's a extreme case, it's OK to raise an exception
|
172
|
-
raise EventCorruption(
|
193
|
+
raise EventCorruption("Error: Event hash failed.", response.result.envelope)
|
173
194
|
|
174
195
|
response.result.signature_verification = self.verify_signature(response.result.envelope)
|
175
196
|
|
@@ -173,6 +173,12 @@ class SearchOrder(str, enum.Enum):
|
|
173
173
|
ASC = "desc"
|
174
174
|
DESC = "asc"
|
175
175
|
|
176
|
+
def __str__(self):
|
177
|
+
return str(self.value)
|
178
|
+
|
179
|
+
def __repr__(self):
|
180
|
+
return str(self.value)
|
181
|
+
|
176
182
|
|
177
183
|
class SearchOrderBy(str, enum.Enum):
|
178
184
|
ACTOR = "actor"
|
@@ -184,6 +190,12 @@ class SearchOrderBy(str, enum.Enum):
|
|
184
190
|
TARGET = "target"
|
185
191
|
TIMESTAMP = "timestamp"
|
186
192
|
|
193
|
+
def __str__(self):
|
194
|
+
return str(self.value)
|
195
|
+
|
196
|
+
def __repr__(self):
|
197
|
+
return str(self.value)
|
198
|
+
|
187
199
|
|
188
200
|
class SearchRequest(APIRequestModel):
|
189
201
|
"""
|
@@ -13,6 +13,7 @@ from typing import Dict, List, Optional
|
|
13
13
|
|
14
14
|
import requests
|
15
15
|
from pangea.services.audit.models import Event, EventEnvelope, PublishedRoot
|
16
|
+
from pangea.utils import format_datetime
|
16
17
|
|
17
18
|
Hash = bytes
|
18
19
|
|
@@ -140,7 +141,11 @@ def format_datetime(dt: datetime):
|
|
140
141
|
"""
|
141
142
|
Format a datetime in ISO format, using Z instead of +00:00
|
142
143
|
"""
|
143
|
-
|
144
|
+
ret = dt.isoformat()
|
145
|
+
if dt.tzinfo is not None:
|
146
|
+
return ret.replace("+00:00", "Z")
|
147
|
+
else:
|
148
|
+
return ret + "Z"
|
144
149
|
|
145
150
|
|
146
151
|
def normalize_log(audit: dict) -> dict:
|
@@ -297,7 +297,7 @@ class FileIntel(ServiceBase):
|
|
297
297
|
raw: Optional[bool] = None,
|
298
298
|
) -> PangeaResponse[FileReputationResult]:
|
299
299
|
"""
|
300
|
-
|
300
|
+
Reputation check
|
301
301
|
|
302
302
|
Retrieve hash-based file reputation from a provider, including an optional detailed report.
|
303
303
|
|
@@ -332,7 +332,7 @@ class FileIntel(ServiceBase):
|
|
332
332
|
raw: Optional[bool] = None,
|
333
333
|
) -> PangeaResponse[FileReputationResult]:
|
334
334
|
"""
|
335
|
-
|
335
|
+
Reputation check
|
336
336
|
|
337
337
|
Retrieve hash-based file reputation from a provider, including an optional detailed report.
|
338
338
|
|
@@ -368,7 +368,7 @@ class FileIntel(ServiceBase):
|
|
368
368
|
raw: Optional[bool] = None,
|
369
369
|
) -> PangeaResponse[FileReputationResult]:
|
370
370
|
"""
|
371
|
-
|
371
|
+
Reputation, from filepath
|
372
372
|
|
373
373
|
Retrieve hash-based file reputation from a provider, including an optional detailed report.
|
374
374
|
|
@@ -405,7 +405,7 @@ class FileIntel(ServiceBase):
|
|
405
405
|
raw: Optional[bool] = None,
|
406
406
|
) -> PangeaResponse[FileReputationResult]:
|
407
407
|
"""
|
408
|
-
|
408
|
+
Reputation, from filepath
|
409
409
|
|
410
410
|
Retrieve hash-based file reputation from a provider, including an optional detailed report.
|
411
411
|
This function take care of calculate filepath hash and make the request to service
|
@@ -468,7 +468,7 @@ class DomainIntel(ServiceBase):
|
|
468
468
|
self, domain: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
469
469
|
) -> PangeaResponse[DomainReputationResult]:
|
470
470
|
"""
|
471
|
-
|
471
|
+
Reputation check
|
472
472
|
|
473
473
|
Retrieve reputation for a domain from a provider, including an optional detailed report.
|
474
474
|
|
@@ -497,7 +497,7 @@ class DomainIntel(ServiceBase):
|
|
497
497
|
self, domain: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
498
498
|
) -> PangeaResponse[DomainReputationResult]:
|
499
499
|
"""
|
500
|
-
|
500
|
+
Reputation check
|
501
501
|
|
502
502
|
Retrieve reputation for a domain from a provider, including an optional detailed report.
|
503
503
|
|
@@ -555,7 +555,7 @@ class IpIntel(ServiceBase):
|
|
555
555
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
556
556
|
) -> PangeaResponse[IPReputationResult]:
|
557
557
|
"""
|
558
|
-
|
558
|
+
Reputation
|
559
559
|
|
560
560
|
Retrieve a reputation score for an IP address from a provider, including an optional detailed report.
|
561
561
|
|
@@ -585,7 +585,7 @@ class IpIntel(ServiceBase):
|
|
585
585
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
586
586
|
) -> PangeaResponse[IPReputationResult]:
|
587
587
|
"""
|
588
|
-
|
588
|
+
Reputation
|
589
589
|
|
590
590
|
Retrieve a reputation score for an IP address from a provider, including an optional detailed report.
|
591
591
|
|
@@ -614,13 +614,13 @@ class IpIntel(ServiceBase):
|
|
614
614
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
615
615
|
) -> PangeaResponse[IPGeolocateResult]:
|
616
616
|
"""
|
617
|
-
Geolocate
|
617
|
+
Geolocate
|
618
618
|
|
619
619
|
Retrieve information about the location of an IP address.
|
620
620
|
|
621
621
|
Args:
|
622
622
|
ip (str): IP address to be geolocated
|
623
|
-
provider (str, optional): Use geolocation data from this provider ("
|
623
|
+
provider (str, optional): Use geolocation data from this provider ("digitalelement"). Default provider defined by the configuration.
|
624
624
|
verbose (bool, optional): Echo the API parameters in the response
|
625
625
|
raw (bool, optional): Include raw data from this provider
|
626
626
|
|
@@ -632,7 +632,7 @@ class IpIntel(ServiceBase):
|
|
632
632
|
response.result field. Available response fields can be found in our [API documentation](/docs/api/ip-intel)
|
633
633
|
|
634
634
|
Examples:
|
635
|
-
response = ip_intel.geolocate(ip="93.231.182.110", provider="
|
635
|
+
response = ip_intel.geolocate(ip="93.231.182.110", provider="digitalelement")
|
636
636
|
"""
|
637
637
|
input = IPGeolocateRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
638
638
|
response = self.request.post("geolocate", data=input.dict(exclude_none=True))
|
@@ -643,13 +643,13 @@ class IpIntel(ServiceBase):
|
|
643
643
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
644
644
|
) -> PangeaResponse[IPDomainResult]:
|
645
645
|
"""
|
646
|
-
|
646
|
+
Domain
|
647
647
|
|
648
648
|
Retrieve the domain name associated with an IP address.
|
649
649
|
|
650
650
|
Args:
|
651
651
|
ip (str): IP address to be geolocated
|
652
|
-
provider (str, optional): Use geolocation data from this provider ("
|
652
|
+
provider (str, optional): Use geolocation data from this provider ("digitalelement"). Default provider defined by the configuration.
|
653
653
|
verbose (bool, optional): Echo the API parameters in the response
|
654
654
|
raw (bool, optional): Include raw data from this provider
|
655
655
|
|
@@ -661,7 +661,7 @@ class IpIntel(ServiceBase):
|
|
661
661
|
response.result field. Available response fields can be found in our [API documentation](/docs/api/ip-intel)
|
662
662
|
|
663
663
|
Examples:
|
664
|
-
response = ip_intel.get_domain(ip="93.231.182.110", provider="
|
664
|
+
response = ip_intel.get_domain(ip="93.231.182.110", provider="digitalelement")
|
665
665
|
"""
|
666
666
|
input = IPDomainRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
667
667
|
response = self.request.post("domain", data=input.dict(exclude_none=True))
|
@@ -672,13 +672,13 @@ class IpIntel(ServiceBase):
|
|
672
672
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
673
673
|
) -> PangeaResponse[IPVPNResult]:
|
674
674
|
"""
|
675
|
-
|
675
|
+
VPN
|
676
676
|
|
677
677
|
Determine if an IP address is provided by a VPN service.
|
678
678
|
|
679
679
|
Args:
|
680
680
|
ip (str): IP address to be geolocated
|
681
|
-
provider (str, optional): Use geolocation data from this provider ("
|
681
|
+
provider (str, optional): Use geolocation data from this provider ("digitalelement"). Default provider defined by the configuration.
|
682
682
|
verbose (bool, optional): Echo the API parameters in the response
|
683
683
|
raw (bool, optional): Include raw data from this provider
|
684
684
|
|
@@ -690,7 +690,7 @@ class IpIntel(ServiceBase):
|
|
690
690
|
response.result field. Available response fields can be found in our [API documentation](/docs/api/ip-intel)
|
691
691
|
|
692
692
|
Examples:
|
693
|
-
response = ip_intel.is_vpn(ip="93.231.182.110", provider="
|
693
|
+
response = ip_intel.is_vpn(ip="93.231.182.110", provider="digitalelement")
|
694
694
|
"""
|
695
695
|
input = IPVPNRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
696
696
|
response = self.request.post("vpn", data=input.dict(exclude_none=True))
|
@@ -701,13 +701,13 @@ class IpIntel(ServiceBase):
|
|
701
701
|
self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
702
702
|
) -> PangeaResponse[IPProxyResult]:
|
703
703
|
"""
|
704
|
-
|
704
|
+
Proxy
|
705
705
|
|
706
706
|
Determine if an IP address is provided by a proxy service.
|
707
707
|
|
708
708
|
Args:
|
709
709
|
ip (str): IP address to be geolocated
|
710
|
-
provider (str, optional): Use geolocation data from this provider ("
|
710
|
+
provider (str, optional): Use geolocation data from this provider ("digitalelement"). Default provider defined by the configuration.
|
711
711
|
verbose (bool, optional): Echo the API parameters in the response
|
712
712
|
raw (bool, optional): Include raw data from this provider
|
713
713
|
|
@@ -719,7 +719,7 @@ class IpIntel(ServiceBase):
|
|
719
719
|
response.result field. Available response fields can be found in our [API documentation](/docs/api/ip-intel)
|
720
720
|
|
721
721
|
Examples:
|
722
|
-
response = ip_intel.is_proxy(ip="93.231.182.110", provider="
|
722
|
+
response = ip_intel.is_proxy(ip="93.231.182.110", provider="digitalelement")
|
723
723
|
"""
|
724
724
|
input = IPProxyRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
|
725
725
|
response = self.request.post("proxy", data=input.dict(exclude_none=True))
|
@@ -759,7 +759,7 @@ class UrlIntel(ServiceBase):
|
|
759
759
|
self, url: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
760
760
|
) -> PangeaResponse[URLReputationResult]:
|
761
761
|
"""
|
762
|
-
|
762
|
+
Reputation check
|
763
763
|
|
764
764
|
Retrieve URL address reputation from a provider.
|
765
765
|
|
@@ -789,7 +789,7 @@ class UrlIntel(ServiceBase):
|
|
789
789
|
self, url: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
|
790
790
|
) -> PangeaResponse[URLReputationResult]:
|
791
791
|
"""
|
792
|
-
|
792
|
+
Reputation check
|
793
793
|
|
794
794
|
Retrieve URL address reputation from a provider.
|
795
795
|
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Copyright 2022 Pangea Cyber Corporation
|
2
|
+
# Author: Pangea Cyber Corporation
|
3
|
+
from typing import Optional
|
4
|
+
|
5
|
+
from pangea.response import APIRequestModel, PangeaResponseResult
|
6
|
+
from pangea.services.vault.models.common import (
|
7
|
+
AsymmetricAlgorithm,
|
8
|
+
CommonGenerateRequest,
|
9
|
+
CommonGenerateResult,
|
10
|
+
CommonStoreRequest,
|
11
|
+
CommonStoreResult,
|
12
|
+
EncodedPrivateKey,
|
13
|
+
EncodedPublicKey,
|
14
|
+
KeyPurpose,
|
15
|
+
)
|
16
|
+
|
17
|
+
|
18
|
+
class AsymmetricGenerateRequest(CommonGenerateRequest):
|
19
|
+
algorithm: AsymmetricAlgorithm
|
20
|
+
purpose: KeyPurpose
|
21
|
+
|
22
|
+
|
23
|
+
class AsymmetricGenerateResult(CommonGenerateResult):
|
24
|
+
algorithm: str
|
25
|
+
purpose: str
|
26
|
+
public_key: EncodedPublicKey
|
27
|
+
|
28
|
+
|
29
|
+
class AsymmetricStoreRequest(CommonStoreRequest):
|
30
|
+
algorithm: AsymmetricAlgorithm
|
31
|
+
public_key: EncodedPublicKey
|
32
|
+
private_key: EncodedPrivateKey
|
33
|
+
purpose: KeyPurpose
|
34
|
+
|
35
|
+
|
36
|
+
class AsymmetricStoreResult(CommonStoreResult):
|
37
|
+
algorithm: str
|
38
|
+
purpose: str
|
39
|
+
public_key: EncodedPublicKey
|
40
|
+
|
41
|
+
|
42
|
+
class SignRequest(APIRequestModel):
|
43
|
+
id: str
|
44
|
+
message: str
|
45
|
+
version: Optional[int] = None
|
46
|
+
|
47
|
+
|
48
|
+
class SignResult(PangeaResponseResult):
|
49
|
+
id: str
|
50
|
+
version: int
|
51
|
+
algorithm: str
|
52
|
+
signature: str
|
53
|
+
public_key: Optional[EncodedPublicKey] = None
|
54
|
+
|
55
|
+
|
56
|
+
class VerifyRequest(APIRequestModel):
|
57
|
+
id: str
|
58
|
+
message: str
|
59
|
+
signature: str
|
60
|
+
version: Optional[int] = None
|
61
|
+
|
62
|
+
|
63
|
+
class VerifyResult(PangeaResponseResult):
|
64
|
+
id: str
|
65
|
+
version: int
|
66
|
+
algorithm: str
|
67
|
+
valid_signature: bool
|