pangea-sdk 6.5.0__py3-none-any.whl → 6.6.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/_typing.py +26 -1
- pangea/asyncio/services/ai_guard.py +29 -4
- pangea/asyncio/services/intel.py +160 -95
- pangea/services/ai_guard.py +91 -13
- pangea/services/intel.py +187 -252
- {pangea_sdk-6.5.0.dist-info → pangea_sdk-6.6.0.dist-info}/METADATA +3 -3
- pangea_sdk-6.6.0.dist-info/RECORD +62 -0
- {pangea_sdk-6.5.0.dist-info → pangea_sdk-6.6.0.dist-info}/WHEEL +1 -1
- pangea_sdk-6.5.0.dist-info/RECORD +0 -62
pangea/services/intel.py
CHANGED
@@ -8,8 +8,9 @@ from __future__ import annotations
|
|
8
8
|
|
9
9
|
import enum
|
10
10
|
import hashlib
|
11
|
-
from typing import Dict, List, Literal, Optional
|
11
|
+
from typing import Any, Dict, List, Literal, Optional
|
12
12
|
|
13
|
+
from pangea._typing import SequenceNotStr
|
13
14
|
from pangea.exceptions import PangeaException
|
14
15
|
from pangea.response import APIRequestModel, PangeaResponse, PangeaResponseResult
|
15
16
|
from pangea.services.base import ServiceBase
|
@@ -31,18 +32,25 @@ class IntelCommonRequest(APIRequestModel):
|
|
31
32
|
|
32
33
|
|
33
34
|
class IntelCommonResult(PangeaResponseResult):
|
35
|
+
parameters: Optional[dict[str, Any]] = None
|
36
|
+
"""The parameters, which were passed in the request, echoed back"""
|
37
|
+
|
38
|
+
raw_data: Optional[dict[str, Any]] = None
|
34
39
|
"""
|
35
|
-
|
40
|
+
The raw data from the provider. Each provider's data will have its own
|
41
|
+
format
|
36
42
|
"""
|
37
43
|
|
38
|
-
parameters: Optional[Dict] = None
|
39
|
-
raw_data: Optional[Dict] = None
|
40
|
-
|
41
44
|
|
42
45
|
class IntelReputationData(PangeaResponseResult):
|
43
|
-
category:
|
44
|
-
|
45
|
-
|
46
|
+
category: Optional[list[str]] = None
|
47
|
+
"""The categories that apply to this indicator as determined by the provider"""
|
48
|
+
|
49
|
+
score: Optional[int] = None
|
50
|
+
"""The score, given by the Pangea service, for the indicator"""
|
51
|
+
|
52
|
+
verdict: Optional[Literal["malicious", "suspicious", "unknown", "benign"]] = None
|
53
|
+
"""The verdict, given by the Pangea service, for the indicator"""
|
46
54
|
|
47
55
|
|
48
56
|
class FileReputationRequest(IntelCommonRequest):
|
@@ -105,42 +113,6 @@ class FileReputationBulkResult(IntelCommonResult):
|
|
105
113
|
data: Dict[str, FileReputationData]
|
106
114
|
|
107
115
|
|
108
|
-
class IPCommonRequest(IntelCommonRequest):
|
109
|
-
"""
|
110
|
-
IP common request data
|
111
|
-
ip (str): IP address to search for reputation information
|
112
|
-
"""
|
113
|
-
|
114
|
-
ip: str
|
115
|
-
|
116
|
-
|
117
|
-
class IPCommonBulkRequest(IntelCommonRequest):
|
118
|
-
"""
|
119
|
-
IP common request data
|
120
|
-
ips (List[str]): IP addresses to search for reputation information
|
121
|
-
"""
|
122
|
-
|
123
|
-
ips: List[str]
|
124
|
-
|
125
|
-
|
126
|
-
class IPReputationRequest(IPCommonRequest):
|
127
|
-
"""
|
128
|
-
IP reputation request data
|
129
|
-
|
130
|
-
"""
|
131
|
-
|
132
|
-
pass
|
133
|
-
|
134
|
-
|
135
|
-
class IPReputationBulkRequest(IPCommonBulkRequest):
|
136
|
-
"""
|
137
|
-
IP reputation bulk request data
|
138
|
-
|
139
|
-
"""
|
140
|
-
|
141
|
-
pass
|
142
|
-
|
143
|
-
|
144
116
|
class IPReputationData(IntelReputationData):
|
145
117
|
"""
|
146
118
|
IP reputation information
|
@@ -150,176 +122,87 @@ class IPReputationData(IntelReputationData):
|
|
150
122
|
|
151
123
|
|
152
124
|
class IPReputationResult(IntelCommonResult):
|
153
|
-
"""
|
154
|
-
IP reputation result
|
155
|
-
"""
|
156
|
-
|
157
125
|
data: IPReputationData
|
158
126
|
|
159
127
|
|
160
128
|
class IPReputationBulkResult(IntelCommonResult):
|
161
|
-
|
162
|
-
IP reputation result
|
163
|
-
"""
|
164
|
-
|
165
|
-
data: Dict[str, IPReputationData]
|
129
|
+
data: dict[str, IPReputationData]
|
166
130
|
|
167
131
|
|
168
|
-
class
|
169
|
-
|
170
|
-
IP
|
171
|
-
"""
|
172
|
-
|
173
|
-
pass
|
174
|
-
|
175
|
-
|
176
|
-
class IPGeolocateBulkRequest(IPCommonBulkRequest):
|
177
|
-
"""
|
178
|
-
IP geolocate bulk request data
|
132
|
+
class IPGeolocateData(PangeaResponseResult):
|
133
|
+
country: Optional[str] = None
|
134
|
+
"""The country where the IP is located"""
|
179
135
|
|
180
|
-
|
136
|
+
city: Optional[str] = None
|
137
|
+
"""The city where the IP is located"""
|
181
138
|
|
182
|
-
|
139
|
+
latitude: Optional[float] = None
|
140
|
+
"""The latitude of the IP"""
|
183
141
|
|
142
|
+
longitude: Optional[float] = None
|
143
|
+
"""The longitude of the IP"""
|
184
144
|
|
185
|
-
|
186
|
-
"""
|
187
|
-
IP geolocate data
|
188
|
-
"""
|
145
|
+
postal_code: Optional[str] = None
|
146
|
+
"""The postal code where the IP is located"""
|
189
147
|
|
190
|
-
|
191
|
-
|
192
|
-
latitude: float
|
193
|
-
longitude: float
|
194
|
-
postal_code: str
|
195
|
-
country_code: str
|
148
|
+
country_code: Optional[str] = None
|
149
|
+
"""The two-digit country code associated with the IP address"""
|
196
150
|
|
197
151
|
|
198
152
|
class IPGeolocateResult(IntelCommonResult):
|
199
|
-
"""
|
200
|
-
IP geolocate result
|
201
|
-
"""
|
202
|
-
|
203
153
|
data: IPGeolocateData
|
204
154
|
|
205
155
|
|
206
156
|
class IPGeolocateBulkResult(IntelCommonResult):
|
207
|
-
|
208
|
-
IP geolocate result
|
209
|
-
"""
|
210
|
-
|
211
|
-
data: Dict[str, IPGeolocateData]
|
212
|
-
|
213
|
-
|
214
|
-
class IPDomainRequest(IPCommonRequest):
|
215
|
-
"""
|
216
|
-
IP domain request data
|
217
|
-
"""
|
218
|
-
|
219
|
-
pass
|
220
|
-
|
221
|
-
|
222
|
-
class IPDomainBulkRequest(IPCommonBulkRequest):
|
223
|
-
"""
|
224
|
-
IP domain bulk request data
|
225
|
-
|
226
|
-
"""
|
227
|
-
|
228
|
-
pass
|
157
|
+
data: dict[str, IPGeolocateData]
|
229
158
|
|
230
159
|
|
231
160
|
class IPDomainData(PangeaResponseResult):
|
232
|
-
domain_found: bool
|
161
|
+
domain_found: Optional[bool] = None
|
162
|
+
"""True, if the domain was found"""
|
163
|
+
|
233
164
|
domain: Optional[str] = None
|
165
|
+
"""The domain associated with the IP address"""
|
234
166
|
|
235
167
|
|
236
168
|
class IPDomainResult(IntelCommonResult):
|
237
|
-
"""
|
238
|
-
IP domain result
|
239
|
-
"""
|
240
|
-
|
241
169
|
data: IPDomainData
|
242
170
|
|
243
171
|
|
244
172
|
class IPDomainBulkResult(IntelCommonResult):
|
245
|
-
|
246
|
-
IP domain bulk result
|
247
|
-
"""
|
248
|
-
|
249
|
-
data: Dict[str, IPDomainData]
|
250
|
-
|
251
|
-
|
252
|
-
class IPVPNRequest(IPCommonRequest):
|
253
|
-
"""
|
254
|
-
IP VPN request data
|
255
|
-
"""
|
256
|
-
|
257
|
-
pass
|
258
|
-
|
259
|
-
|
260
|
-
class IPVPNBulkRequest(IPCommonBulkRequest):
|
261
|
-
"""
|
262
|
-
IP vpn bulk request data
|
263
|
-
|
264
|
-
"""
|
265
|
-
|
266
|
-
pass
|
173
|
+
data: dict[str, IPDomainData]
|
267
174
|
|
268
175
|
|
269
176
|
class IPVPNData(PangeaResponseResult):
|
270
177
|
is_vpn: bool
|
271
|
-
|
272
|
-
|
273
|
-
class IPVPNResult(IntelCommonResult):
|
274
178
|
"""
|
275
|
-
IP VPN
|
179
|
+
- True - Indicates the IP address belongs to a VPN service
|
180
|
+
- False - Indicates the IP address is not associated with a VPN service
|
276
181
|
"""
|
277
182
|
|
183
|
+
|
184
|
+
class IPVPNResult(IntelCommonResult):
|
278
185
|
data: IPVPNData
|
279
186
|
|
280
187
|
|
281
188
|
class IPVPNBulkResult(IntelCommonResult):
|
282
|
-
|
283
|
-
IP VPN bulk result
|
284
|
-
"""
|
285
|
-
|
286
|
-
data: Dict[str, IPVPNData]
|
287
|
-
|
288
|
-
|
289
|
-
class IPProxyRequest(IPCommonRequest):
|
290
|
-
"""
|
291
|
-
IP VPN request data
|
292
|
-
"""
|
293
|
-
|
294
|
-
pass
|
295
|
-
|
296
|
-
|
297
|
-
class IPProxyBulkRequest(IPCommonBulkRequest):
|
298
|
-
"""
|
299
|
-
IP VPN bulk request data
|
300
|
-
"""
|
301
|
-
|
302
|
-
pass
|
189
|
+
data: dict[str, IPVPNData]
|
303
190
|
|
304
191
|
|
305
192
|
class IPProxyData(PangeaResponseResult):
|
306
193
|
is_proxy: bool
|
307
|
-
|
308
|
-
|
309
|
-
class IPProxyResult(IntelCommonResult):
|
310
194
|
"""
|
311
|
-
IP proxy
|
195
|
+
- True - Indicates the IP address belongs to a proxy service
|
196
|
+
- False - Indicates the IP address is not associated with a proxy service
|
312
197
|
"""
|
313
198
|
|
199
|
+
|
200
|
+
class IPProxyResult(IntelCommonResult):
|
314
201
|
data: IPProxyData
|
315
202
|
|
316
203
|
|
317
204
|
class IPProxyBulkResult(IntelCommonResult):
|
318
|
-
|
319
|
-
IP proxy bulk result
|
320
|
-
"""
|
321
|
-
|
322
|
-
data: Dict[str, IPProxyData]
|
205
|
+
data: dict[str, IPProxyData]
|
323
206
|
|
324
207
|
|
325
208
|
class DomainCommonRequest(IntelCommonRequest):
|
@@ -799,33 +682,26 @@ class DomainIntel(ServiceBase):
|
|
799
682
|
|
800
683
|
|
801
684
|
class IpIntel(ServiceBase):
|
802
|
-
"""
|
803
|
-
|
804
|
-
Provides methods to interact with [Pangea IP Intel Service](/docs/api/ip-intel)
|
685
|
+
"""
|
686
|
+
IP Intel service client
|
805
687
|
|
806
|
-
|
807
|
-
PANGEA_TOKEN - service token which can be found on the Pangea User
|
808
|
-
Console at [https://console.pangea.cloud/project/tokens](https://console.pangea.cloud/project/tokens)
|
688
|
+
Provides methods to interact with the Pangea IP Intel Service.
|
809
689
|
|
810
690
|
Examples:
|
811
|
-
import os
|
812
|
-
|
813
|
-
# Pangea SDK
|
814
|
-
from pangea.config import PangeaConfig
|
815
691
|
from pangea.services import IpIntel
|
816
692
|
|
817
|
-
|
818
|
-
|
819
|
-
ip_intel_config = PangeaConfig(domain="pangea.cloud")
|
820
|
-
|
821
|
-
# Setup Pangea IP Intel service
|
822
|
-
ip_intel = IpIntel(token=PANGEA_TOKEN, config=ip_intel_config)
|
693
|
+
ip_intel = IpIntel(token="my_api_token")
|
823
694
|
"""
|
824
695
|
|
825
696
|
service_name = "ip-intel"
|
826
697
|
|
827
698
|
def reputation(
|
828
|
-
self,
|
699
|
+
self,
|
700
|
+
ip: str,
|
701
|
+
*,
|
702
|
+
verbose: bool | None = None,
|
703
|
+
raw: bool | None = None,
|
704
|
+
provider: Literal["crowdstrike", "cymru"] | None = None,
|
829
705
|
) -> PangeaResponse[IPReputationResult]:
|
830
706
|
"""
|
831
707
|
Reputation
|
@@ -835,10 +711,10 @@ class IpIntel(ServiceBase):
|
|
835
711
|
OperationId: ip_intel_post_v1_reputation
|
836
712
|
|
837
713
|
Args:
|
838
|
-
ip
|
839
|
-
verbose
|
840
|
-
raw
|
841
|
-
provider
|
714
|
+
ip: The IP to be looked up
|
715
|
+
verbose: Echo the API parameters in the response
|
716
|
+
raw: Include raw data from this provider
|
717
|
+
provider: Use reputation data from this provider
|
842
718
|
|
843
719
|
Raises:
|
844
720
|
PangeaAPIException: If an API Error happens
|
@@ -853,11 +729,17 @@ class IpIntel(ServiceBase):
|
|
853
729
|
provider="crowdstrike",
|
854
730
|
)
|
855
731
|
"""
|
856
|
-
|
857
|
-
|
732
|
+
return self.request.post(
|
733
|
+
"v1/reputation", IPReputationResult, data={"ip": ip, "verbose": verbose, "raw": raw, "provider": provider}
|
734
|
+
)
|
858
735
|
|
859
736
|
def reputation_bulk(
|
860
|
-
self,
|
737
|
+
self,
|
738
|
+
ips: SequenceNotStr[str],
|
739
|
+
*,
|
740
|
+
verbose: bool | None = None,
|
741
|
+
raw: bool | None = None,
|
742
|
+
provider: Literal["crowdstrike", "cymru"] | None = None,
|
861
743
|
) -> PangeaResponse[IPReputationBulkResult]:
|
862
744
|
"""
|
863
745
|
Reputation V2
|
@@ -867,10 +749,10 @@ class IpIntel(ServiceBase):
|
|
867
749
|
OperationId: ip_intel_post_v2_reputation
|
868
750
|
|
869
751
|
Args:
|
870
|
-
ips
|
871
|
-
verbose
|
872
|
-
raw
|
873
|
-
provider
|
752
|
+
ips: The IP to be looked up
|
753
|
+
verbose: Echo the API parameters in the response
|
754
|
+
raw: Include raw data from this provider
|
755
|
+
provider: Use reputation data from this provider
|
874
756
|
|
875
757
|
Raises:
|
876
758
|
PangeaAPIException: If an API Error happens
|
@@ -885,11 +767,19 @@ class IpIntel(ServiceBase):
|
|
885
767
|
provider="crowdstrike",
|
886
768
|
)
|
887
769
|
"""
|
888
|
-
|
889
|
-
|
770
|
+
return self.request.post(
|
771
|
+
"v2/reputation",
|
772
|
+
IPReputationBulkResult,
|
773
|
+
data={"ips": ips, "verbose": verbose, "raw": raw, "provider": provider},
|
774
|
+
)
|
890
775
|
|
891
776
|
def geolocate(
|
892
|
-
self,
|
777
|
+
self,
|
778
|
+
ip: str,
|
779
|
+
*,
|
780
|
+
verbose: bool | None = None,
|
781
|
+
raw: bool | None = None,
|
782
|
+
provider: Literal["digitalenvoy", "digitalelement"] | None = None,
|
893
783
|
) -> PangeaResponse[IPGeolocateResult]:
|
894
784
|
"""
|
895
785
|
Geolocate
|
@@ -899,10 +789,10 @@ class IpIntel(ServiceBase):
|
|
899
789
|
OperationId: ip_intel_post_v1_geolocate
|
900
790
|
|
901
791
|
Args:
|
902
|
-
ip
|
903
|
-
|
904
|
-
|
905
|
-
|
792
|
+
ip: The IP to be looked up
|
793
|
+
verbose: Echo the API parameters in the response
|
794
|
+
raw: Include raw data from this provider
|
795
|
+
provider: Use location data from this provider
|
906
796
|
|
907
797
|
Raises:
|
908
798
|
PangeaAPIException: If an API Error happens
|
@@ -917,11 +807,17 @@ class IpIntel(ServiceBase):
|
|
917
807
|
provider="digitalelement",
|
918
808
|
)
|
919
809
|
"""
|
920
|
-
|
921
|
-
|
810
|
+
return self.request.post(
|
811
|
+
"v1/geolocate", IPGeolocateResult, data={"ip": ip, "verbose": verbose, "raw": raw, "provider": provider}
|
812
|
+
)
|
922
813
|
|
923
814
|
def geolocate_bulk(
|
924
|
-
self,
|
815
|
+
self,
|
816
|
+
ips: SequenceNotStr[str],
|
817
|
+
*,
|
818
|
+
verbose: bool | None = None,
|
819
|
+
raw: bool | None = None,
|
820
|
+
provider: Literal["digitalenvoy", "digitalelement"] | None = None,
|
925
821
|
) -> PangeaResponse[IPGeolocateBulkResult]:
|
926
822
|
"""
|
927
823
|
Geolocate V2
|
@@ -931,10 +827,10 @@ class IpIntel(ServiceBase):
|
|
931
827
|
OperationId: ip_intel_post_v2_geolocate
|
932
828
|
|
933
829
|
Args:
|
934
|
-
ips
|
935
|
-
|
936
|
-
|
937
|
-
|
830
|
+
ips: The IP(s) to be looked up
|
831
|
+
verbose: Echo the API parameters in the response
|
832
|
+
raw: Include raw data from this provider
|
833
|
+
provider: Use location data from this provider
|
938
834
|
|
939
835
|
Raises:
|
940
836
|
PangeaAPIException: If an API Error happens
|
@@ -949,11 +845,19 @@ class IpIntel(ServiceBase):
|
|
949
845
|
provider="digitalelement",
|
950
846
|
)
|
951
847
|
"""
|
952
|
-
|
953
|
-
|
848
|
+
return self.request.post(
|
849
|
+
"v2/geolocate",
|
850
|
+
IPGeolocateBulkResult,
|
851
|
+
data={"ips": ips, "verbose": verbose, "raw": raw, "provider": provider},
|
852
|
+
)
|
954
853
|
|
955
854
|
def get_domain(
|
956
|
-
self,
|
855
|
+
self,
|
856
|
+
ip: str,
|
857
|
+
*,
|
858
|
+
verbose: bool | None = None,
|
859
|
+
raw: bool | None = None,
|
860
|
+
provider: Literal["digitalenvoy", "digitalelement"] | None = None,
|
957
861
|
) -> PangeaResponse[IPDomainResult]:
|
958
862
|
"""
|
959
863
|
Domain
|
@@ -963,10 +867,10 @@ class IpIntel(ServiceBase):
|
|
963
867
|
OperationId: ip_intel_post_v1_domain
|
964
868
|
|
965
869
|
Args:
|
966
|
-
ip
|
967
|
-
|
968
|
-
|
969
|
-
|
870
|
+
ip: The IP to be looked up
|
871
|
+
verbose: Echo the API parameters in the response
|
872
|
+
raw: Include raw data from this provider
|
873
|
+
provider: Use domain data from this provider
|
970
874
|
|
971
875
|
Raises:
|
972
876
|
PangeaAPIException: If an API Error happens
|
@@ -981,11 +885,17 @@ class IpIntel(ServiceBase):
|
|
981
885
|
provider="digitalelement",
|
982
886
|
)
|
983
887
|
"""
|
984
|
-
|
985
|
-
|
888
|
+
return self.request.post(
|
889
|
+
"v1/domain", IPDomainResult, data={"ip": ip, "verbose": verbose, "raw": raw, "provider": provider}
|
890
|
+
)
|
986
891
|
|
987
892
|
def get_domain_bulk(
|
988
|
-
self,
|
893
|
+
self,
|
894
|
+
ips: SequenceNotStr[str],
|
895
|
+
*,
|
896
|
+
verbose: bool | None = None,
|
897
|
+
raw: bool | None = None,
|
898
|
+
provider: Literal["digitalenvoy", "digitalelement"] | None = None,
|
989
899
|
) -> PangeaResponse[IPDomainBulkResult]:
|
990
900
|
"""
|
991
901
|
Domain V2
|
@@ -995,10 +905,10 @@ class IpIntel(ServiceBase):
|
|
995
905
|
OperationId: ip_intel_post_v2_domain
|
996
906
|
|
997
907
|
Args:
|
998
|
-
ips (
|
999
|
-
|
1000
|
-
|
1001
|
-
|
908
|
+
ips: The IP(s) to be looked up
|
909
|
+
verbose: Echo the API parameters in the response
|
910
|
+
raw: Include raw data from this provider
|
911
|
+
provider: Use domain data from this provider
|
1002
912
|
|
1003
913
|
Raises:
|
1004
914
|
PangeaAPIException: If an API Error happens
|
@@ -1013,11 +923,17 @@ class IpIntel(ServiceBase):
|
|
1013
923
|
provider="digitalelement",
|
1014
924
|
)
|
1015
925
|
"""
|
1016
|
-
|
1017
|
-
|
926
|
+
return self.request.post(
|
927
|
+
"v2/domain", IPDomainBulkResult, data={"ips": ips, "verbose": verbose, "raw": raw, "provider": provider}
|
928
|
+
)
|
1018
929
|
|
1019
930
|
def is_vpn(
|
1020
|
-
self,
|
931
|
+
self,
|
932
|
+
ip: str,
|
933
|
+
*,
|
934
|
+
verbose: bool | None = None,
|
935
|
+
raw: bool | None = None,
|
936
|
+
provider: Literal["digitalenvoy", "digitalelement"] | None = None,
|
1021
937
|
) -> PangeaResponse[IPVPNResult]:
|
1022
938
|
"""
|
1023
939
|
VPN
|
@@ -1027,10 +943,10 @@ class IpIntel(ServiceBase):
|
|
1027
943
|
OperationId: ip_intel_post_v1_vpn
|
1028
944
|
|
1029
945
|
Args:
|
1030
|
-
ip
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
946
|
+
ip: The IP to be looked up
|
947
|
+
verbose: Echo the API parameters in the response
|
948
|
+
raw: Include raw data from this provider
|
949
|
+
provider: Use vpn data from this provider
|
1034
950
|
|
1035
951
|
Raises:
|
1036
952
|
PangeaAPIException: If an API Error happens
|
@@ -1045,11 +961,17 @@ class IpIntel(ServiceBase):
|
|
1045
961
|
provider="digitalelement",
|
1046
962
|
)
|
1047
963
|
"""
|
1048
|
-
|
1049
|
-
|
964
|
+
return self.request.post(
|
965
|
+
"v1/vpn", IPVPNResult, {"ip": ip, "verbose": verbose, "raw": raw, "provider": provider}
|
966
|
+
)
|
1050
967
|
|
1051
968
|
def is_vpn_bulk(
|
1052
|
-
self,
|
969
|
+
self,
|
970
|
+
ips: SequenceNotStr[str],
|
971
|
+
*,
|
972
|
+
verbose: bool | None = None,
|
973
|
+
raw: bool | None = None,
|
974
|
+
provider: Literal["digitalenvoy", "digitalelement"] | None = None,
|
1053
975
|
) -> PangeaResponse[IPVPNBulkResult]:
|
1054
976
|
"""
|
1055
977
|
VPN V2
|
@@ -1059,10 +981,10 @@ class IpIntel(ServiceBase):
|
|
1059
981
|
OperationId: ip_intel_post_v2_vpn
|
1060
982
|
|
1061
983
|
Args:
|
1062
|
-
ips
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
984
|
+
ips: The IP(s) to be looked up
|
985
|
+
verbose: Echo the API parameters in the response
|
986
|
+
raw: Include raw data from this provider
|
987
|
+
provider: Use vpn data from this provider
|
1066
988
|
|
1067
989
|
Raises:
|
1068
990
|
PangeaAPIException: If an API Error happens
|
@@ -1077,11 +999,17 @@ class IpIntel(ServiceBase):
|
|
1077
999
|
provider="digitalelement",
|
1078
1000
|
)
|
1079
1001
|
"""
|
1080
|
-
|
1081
|
-
|
1002
|
+
return self.request.post(
|
1003
|
+
"v2/vpn", IPVPNBulkResult, data={"ips": ips, "verbose": verbose, "raw": raw, "provider": provider}
|
1004
|
+
)
|
1082
1005
|
|
1083
1006
|
def is_proxy(
|
1084
|
-
self,
|
1007
|
+
self,
|
1008
|
+
ip: str,
|
1009
|
+
*,
|
1010
|
+
verbose: bool | None = None,
|
1011
|
+
raw: bool | None = None,
|
1012
|
+
provider: Literal["digitalenvoy", "digitalelement"] | None = None,
|
1085
1013
|
) -> PangeaResponse[IPProxyResult]:
|
1086
1014
|
"""
|
1087
1015
|
Proxy
|
@@ -1091,10 +1019,10 @@ class IpIntel(ServiceBase):
|
|
1091
1019
|
OperationId: ip_intel_post_v1_proxy
|
1092
1020
|
|
1093
1021
|
Args:
|
1094
|
-
ip
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1022
|
+
ip: The IP to be looked up
|
1023
|
+
verbose: Echo the API parameters in the response
|
1024
|
+
raw: Include raw data from this provider
|
1025
|
+
provider: Use proxy data from this provider
|
1098
1026
|
|
1099
1027
|
Raises:
|
1100
1028
|
PangeaAPIException: If an API Error happens
|
@@ -1109,11 +1037,17 @@ class IpIntel(ServiceBase):
|
|
1109
1037
|
provider="digitalelement",
|
1110
1038
|
)
|
1111
1039
|
"""
|
1112
|
-
|
1113
|
-
|
1040
|
+
return self.request.post(
|
1041
|
+
"v1/proxy", IPProxyResult, data={"ip": ip, "verbose": verbose, "raw": raw, "provider": provider}
|
1042
|
+
)
|
1114
1043
|
|
1115
1044
|
def is_proxy_bulk(
|
1116
|
-
self,
|
1045
|
+
self,
|
1046
|
+
ips: SequenceNotStr[str],
|
1047
|
+
*,
|
1048
|
+
verbose: bool | None = None,
|
1049
|
+
raw: bool | None = None,
|
1050
|
+
provider: Literal["digitalenvoy", "digitalelement"] | None = None,
|
1117
1051
|
) -> PangeaResponse[IPProxyBulkResult]:
|
1118
1052
|
"""
|
1119
1053
|
Proxy V2
|
@@ -1123,10 +1057,10 @@ class IpIntel(ServiceBase):
|
|
1123
1057
|
OperationId: ip_intel_post_v2_proxy
|
1124
1058
|
|
1125
1059
|
Args:
|
1126
|
-
ips
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1060
|
+
ips: The IP(s) to be looked up
|
1061
|
+
verbose: Echo the API parameters in the response
|
1062
|
+
raw: Include raw data from this provider
|
1063
|
+
provider: Use proxy data from this provider
|
1130
1064
|
|
1131
1065
|
Raises:
|
1132
1066
|
PangeaAPIException: If an API Error happens
|
@@ -1141,8 +1075,9 @@ class IpIntel(ServiceBase):
|
|
1141
1075
|
provider="digitalelement",
|
1142
1076
|
)
|
1143
1077
|
"""
|
1144
|
-
|
1145
|
-
|
1078
|
+
return self.request.post(
|
1079
|
+
"v2/proxy", IPProxyBulkResult, data={"ips": ips, "verbose": verbose, "raw": raw, "provider": provider}
|
1080
|
+
)
|
1146
1081
|
|
1147
1082
|
|
1148
1083
|
class UrlIntel(ServiceBase):
|
@@ -1727,10 +1662,10 @@ class UserIntel(ServiceBase):
|
|
1727
1662
|
hash: Password hash
|
1728
1663
|
"""
|
1729
1664
|
|
1730
|
-
if response.result.raw_data is None:
|
1665
|
+
if response.result is None or response.result.raw_data is None:
|
1731
1666
|
raise PangeaException("Need raw data to check if hash is breached. Send request with raw=true")
|
1732
1667
|
|
1733
|
-
hash_data = response.result.raw_data.pop(hash, None)
|
1668
|
+
hash_data = response.result.raw_data.pop(hash, None)
|
1734
1669
|
if hash_data is not None:
|
1735
1670
|
# If hash is present in raw data, it's because it was breached
|
1736
1671
|
return UserIntel.PasswordStatus.BREACHED
|
@@ -1738,7 +1673,7 @@ class UserIntel(ServiceBase):
|
|
1738
1673
|
# If it's not present, should check if I have all breached hash
|
1739
1674
|
# Server will return a maximum of 1000 hash, so if breached count is greater than that,
|
1740
1675
|
# I can't conclude is password is or is not breached
|
1741
|
-
if len(response.result.raw_data.keys()) >= 1000:
|
1676
|
+
if len(response.result.raw_data.keys()) >= 1000:
|
1742
1677
|
return UserIntel.PasswordStatus.INCONCLUSIVE
|
1743
1678
|
else:
|
1744
1679
|
return UserIntel.PasswordStatus.UNBREACHED
|