pangea-sdk 1.4.0__py3-none-any.whl → 1.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pangea/__init__.py +1 -1
- pangea/deep_verify.py +2 -2
- pangea/dump_audit.py +3 -9
- pangea/exceptions.py +34 -5
- pangea/request.py +40 -7
- pangea/response.py +8 -0
- pangea/services/__init__.py +1 -0
- pangea/services/audit/audit.py +23 -2
- pangea/services/audit/models.py +12 -0
- pangea/services/audit/util.py +6 -1
- pangea/services/intel.py +22 -22
- pangea/services/vault/models/asymmetric.py +67 -0
- pangea/services/vault/models/common.py +337 -0
- pangea/services/vault/models/secret.py +24 -0
- pangea/services/vault/models/symmetric.py +61 -0
- pangea/services/vault/vault.py +458 -0
- pangea/{tools_util.py → tools.py} +7 -9
- pangea/utils.py +22 -0
- {pangea_sdk-1.4.0.dist-info → pangea_sdk-1.5.0.dist-info}/METADATA +4 -3
- pangea_sdk-1.5.0.dist-info/RECORD +30 -0
- {pangea_sdk-1.4.0.dist-info → pangea_sdk-1.5.0.dist-info}/WHEEL +1 -1
- pangea_sdk-1.4.0.dist-info/RECORD +0 -24
pangea/__init__.py
CHANGED
pangea/deep_verify.py
CHANGED
@@ -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)
|
pangea/dump_audit.py
CHANGED
@@ -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:
|
pangea/exceptions.py
CHANGED
@@ -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"""
|
pangea/request.py
CHANGED
@@ -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)
|
pangea/response.py
CHANGED
@@ -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):
|
pangea/services/__init__.py
CHANGED
pangea/services/audit/audit.py
CHANGED
@@ -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
|
|
pangea/services/audit/models.py
CHANGED
@@ -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
|
"""
|
pangea/services/audit/util.py
CHANGED
@@ -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:
|
pangea/services/intel.py
CHANGED
@@ -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
|