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.
Files changed (30) hide show
  1. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/PKG-INFO +4 -3
  2. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/README.md +2 -2
  3. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/__init__.py +1 -1
  4. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/deep_verify.py +2 -2
  5. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/dump_audit.py +3 -9
  6. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/exceptions.py +34 -5
  7. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/request.py +40 -7
  8. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/response.py +8 -0
  9. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/__init__.py +1 -0
  10. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/audit/audit.py +23 -2
  11. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/audit/models.py +12 -0
  12. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/audit/util.py +6 -1
  13. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/intel.py +22 -22
  14. pangea_sdk-1.5.0/pangea/services/vault/models/asymmetric.py +67 -0
  15. pangea_sdk-1.5.0/pangea/services/vault/models/common.py +337 -0
  16. pangea_sdk-1.5.0/pangea/services/vault/models/secret.py +24 -0
  17. pangea_sdk-1.5.0/pangea/services/vault/models/symmetric.py +61 -0
  18. pangea_sdk-1.5.0/pangea/services/vault/vault.py +458 -0
  19. pangea_sdk-1.4.0/pangea/tools_util.py → pangea_sdk-1.5.0/pangea/tools.py +7 -9
  20. pangea_sdk-1.5.0/pangea/utils.py +22 -0
  21. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pyproject.toml +2 -1
  22. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/audit_logger.py +0 -0
  23. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/config.py +0 -0
  24. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/deprecated.py +0 -0
  25. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/audit/exceptions.py +0 -0
  26. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/audit/signing.py +0 -0
  27. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/base.py +0 -0
  28. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/embargo.py +0 -0
  29. {pangea_sdk-1.4.0 → pangea_sdk-1.5.0}/pangea/services/redact.py +0 -0
  30. {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.4.0
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
- [![Discord](https://img.shields.io/discord/1017567751818182786?color=%23551b76&label=Discord&logo=discord&logoColor=%23FFFFFF&style=for-the-badge)](https://discord.gg/z7yXhC7cQr)
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
- [![Discord](https://img.shields.io/discord/1017567751818182786?color=%23551b76&label=Discord&logo=discord&logoColor=%23FFFFFF&style=for-the-badge)](https://discord.gg/z7yXhC7cQr)
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>
@@ -1,4 +1,4 @@
1
- __version__ = "1.4.0"
1
+ __version__ = "1.5.0"
2
2
 
3
3
  from pangea.config import PangeaConfig
4
4
  from pangea.request import PangeaRequest
@@ -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.tools_util import Event, SequenceFollower, exit_with_error, file_events, init_audit, print_progress_bar
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] | t.Iterator[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.tools_util import (
15
- filter_deep_none,
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=json_defaults) + "\n")
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:\n"
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 InternalServiceErrorException(PangeaAPIException):
89
- """A pangea service error"""
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 Optional
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: dict = {}) -> PangeaResponse:
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
- self.logger.debug(json.dumps({"service": self.service, "action": "post", "url": url, "data": data}))
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
- {"service": self.service, "action": "api_error", "summary": summary, "result": response.raw_result}
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):
@@ -2,3 +2,4 @@ from .audit.audit import Audit
2
2
  from .embargo import Embargo
3
3
  from .intel import DomainIntel, FileIntel, IpIntel, UrlIntel
4
4
  from .redact import Redact
5
+ from .vault.vault import Vault
@@ -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(f"Error: Event hash failed.", response.result.envelope)
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
- return dt.isoformat().replace("+00:00", "Z")
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
- File reputation
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
- File reputation
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
- File reputation, from filepath
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
- File reputation, from filepath
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
- Domain reputation
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
- Domain reputation
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
- IP reputation
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
- IP reputation
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 an IP
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 ("digitalenvoy"). Default provider defined by the configuration.
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="digitalenvoy")
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
- Look up domain for an IP
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 ("digitalenvoy"). Default provider defined by the configuration.
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="digitalenvoy")
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
- Check if an IP is a VPN
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 ("digitalenvoy"). Default provider defined by the configuration.
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="digitalenvoy")
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
- Check for proxied IPs
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 ("digitalenvoy"). Default provider defined by the configuration.
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="digitalenvoy")
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
- URL reputation
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
- URL reputation
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