python-ipware 2.0.3__tar.gz → 2.0.4__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-ipware
3
- Version: 2.0.3
3
+ Version: 2.0.4
4
4
  Summary: A Python package to retrieve user's IP address
5
5
  Author-email: Val Neekman <info@neekware.com>
6
6
  License: MIT
@@ -216,23 +216,41 @@ If your python server is behind a `known` number of proxies, but you deploy on m
216
216
  You can customize the proxy count by providing your `proxy_count` during initialization when calling `IpWare(proxy_count=2)`.
217
217
 
218
218
  ```python
219
- # In the above scenario, the total number of proxies can be used as a way to filter out unwanted requests.
220
219
  from python_ipware import IpWare
221
220
 
222
- # enforce proxy count
223
- ipw = IpWare(proxy_count=1)
221
+ # Enforce proxy count
222
+ # proxy_count=0 is valid
223
+ # proxy_count=None to disable proxy_count check
224
+ ipw = IpWare(proxy_count=2)
224
225
 
225
- # enforce proxy count and trusted proxies
226
- ipw = IpWare(proxy_count=1, proxy_list=["198.84.193.157"])
226
+ # Example usage in non-strict mode:
227
+ # X-Forwarded-For format: <fake>, <client>, <proxy1>, <proxy2>
228
+ # At least `proxy_count` number of proxies
229
+ ip, trusted_route = ipw.get_client_ip(meta=request.META)
227
230
 
231
+ # Example usage in strict mode:
232
+ # X-Forwarded-For format: <client>, <proxy1>, <proxy2>
233
+ # Exact `proxy_count` number of proxies
234
+ ip, trusted_route = ipw.get_client_ip(meta=request.META, strict=True)
235
+ ```
228
236
 
229
- # usage: non-strict mode (X-Forwarded-For: <fake>, <client>, <proxy1>, <proxy2>)
230
- # total number of ip addresses are greater than the total count
231
- ip, trusted_route = ipw.get_client_ip(meta=request.META)
237
+ ### Proxy Count & Trusted Proxy List Combo
238
+ In this example, we utilize the total number of proxies as a method to filter out unwanted requests while verifying the trust proxies.
232
239
 
240
+ ```python
241
+ from python_ipware import IpWare
233
242
 
234
- # usage: strict mode (X-Forwarded-For: <client>, <proxy1>, <proxy2>)
235
- # total number of ip addresses are exactly equal to client ip + proxy_count
243
+ # Enforce both proxy count and trusted proxies
244
+ ipw = IpWare(proxy_count=1, proxy_list=["198.84.193.157"])
245
+
246
+ # Example usage in non-strict mode:
247
+ # X-Forwarded-For format: <fake>, <client>, <proxy1>, <proxy2>
248
+ # At least `proxy_count` number of proxies
249
+ ip, trusted_route = ipw.get_client_ip(meta=request.META)
250
+
251
+ # Example usage in strict mode:
252
+ # X-Forwarded-For format: <client>, <proxy1>
253
+ # Exact `proxy_count` number of proxies
236
254
  ip, trusted_route = ipw.get_client_ip(meta=request.META, strict=True)
237
255
  ```
238
256
 
@@ -185,23 +185,41 @@ If your python server is behind a `known` number of proxies, but you deploy on m
185
185
  You can customize the proxy count by providing your `proxy_count` during initialization when calling `IpWare(proxy_count=2)`.
186
186
 
187
187
  ```python
188
- # In the above scenario, the total number of proxies can be used as a way to filter out unwanted requests.
189
188
  from python_ipware import IpWare
190
189
 
191
- # enforce proxy count
192
- ipw = IpWare(proxy_count=1)
190
+ # Enforce proxy count
191
+ # proxy_count=0 is valid
192
+ # proxy_count=None to disable proxy_count check
193
+ ipw = IpWare(proxy_count=2)
193
194
 
194
- # enforce proxy count and trusted proxies
195
- ipw = IpWare(proxy_count=1, proxy_list=["198.84.193.157"])
195
+ # Example usage in non-strict mode:
196
+ # X-Forwarded-For format: <fake>, <client>, <proxy1>, <proxy2>
197
+ # At least `proxy_count` number of proxies
198
+ ip, trusted_route = ipw.get_client_ip(meta=request.META)
196
199
 
200
+ # Example usage in strict mode:
201
+ # X-Forwarded-For format: <client>, <proxy1>, <proxy2>
202
+ # Exact `proxy_count` number of proxies
203
+ ip, trusted_route = ipw.get_client_ip(meta=request.META, strict=True)
204
+ ```
197
205
 
198
- # usage: non-strict mode (X-Forwarded-For: <fake>, <client>, <proxy1>, <proxy2>)
199
- # total number of ip addresses are greater than the total count
200
- ip, trusted_route = ipw.get_client_ip(meta=request.META)
206
+ ### Proxy Count & Trusted Proxy List Combo
207
+ In this example, we utilize the total number of proxies as a method to filter out unwanted requests while verifying the trust proxies.
201
208
 
209
+ ```python
210
+ from python_ipware import IpWare
202
211
 
203
- # usage: strict mode (X-Forwarded-For: <client>, <proxy1>, <proxy2>)
204
- # total number of ip addresses are exactly equal to client ip + proxy_count
212
+ # Enforce both proxy count and trusted proxies
213
+ ipw = IpWare(proxy_count=1, proxy_list=["198.84.193.157"])
214
+
215
+ # Example usage in non-strict mode:
216
+ # X-Forwarded-For format: <fake>, <client>, <proxy1>, <proxy2>
217
+ # At least `proxy_count` number of proxies
218
+ ip, trusted_route = ipw.get_client_ip(meta=request.META)
219
+
220
+ # Example usage in strict mode:
221
+ # X-Forwarded-For format: <client>, <proxy1>
222
+ # Exact `proxy_count` number of proxies
205
223
  ip, trusted_route = ipw.get_client_ip(meta=request.META, strict=True)
206
224
  ```
207
225
 
@@ -0,0 +1 @@
1
+ __version__ = "2.0.4"
@@ -144,12 +144,9 @@ class IpWareProxy:
144
144
 
145
145
  def __init__(
146
146
  self,
147
- proxy_count: int = 0,
147
+ proxy_count: Optional[int] = None,
148
148
  proxy_list: Optional[List[str]] = None,
149
149
  ) -> None:
150
- if proxy_count is None or proxy_count < 0:
151
- raise ValueError("proxy_count must be a positive integer")
152
-
153
150
  self.proxy_count = proxy_count
154
151
  self.proxy_list = self._is_valid_proxy_trusted_list(proxy_list or [])
155
152
 
@@ -172,15 +169,14 @@ class IpWareProxy:
172
169
  """
173
170
  Checks if the proxy count is valid
174
171
  @param ip_list: list of ip addresses
175
- @param strict: if True, we must have exactly proxy_count proxies
172
+ @param strict: if True, we must have exactly proxy_count proxies, including `0` proxies
176
173
  @return: True if the proxy count is valid, False otherwise
177
174
  """
178
- if self.proxy_count < 1:
175
+ # No proxy count check is required
176
+ if self.proxy_count is None:
179
177
  return True
180
178
 
181
179
  ip_count: int = len(ip_list)
182
- if ip_count < 1:
183
- return False
184
180
 
185
181
  if strict:
186
182
  # our first proxy takes the last ip address and treats it as client ip
@@ -221,10 +217,6 @@ class IpWareProxy:
221
217
  if not str(value).startswith(self.proxy_list[index]):
222
218
  return False
223
219
 
224
- # now all we need is to return the first ip in the list that is not in the trusted proxy list
225
- # best_client_ip_index = proxy_list_count + 1
226
- # best_client_ip = ip_list[-best_client_ip_index]
227
-
228
220
  return True
229
221
 
230
222
 
@@ -237,11 +229,11 @@ class IpWare(IpWareMeta, IpWareProxy, IpWareIpAddress):
237
229
  self,
238
230
  precedence: Optional[Tuple[str, ...]] = None,
239
231
  leftmost: bool = True,
240
- proxy_count: int = 0,
232
+ proxy_count: Optional[int] = None,
241
233
  proxy_list: Optional[List[str]] = None,
242
234
  ) -> None:
243
235
  IpWareMeta.__init__(self, precedence, leftmost)
244
- IpWareProxy.__init__(self, proxy_count or 0, proxy_list or [])
236
+ IpWareProxy.__init__(self, proxy_count, proxy_list)
245
237
 
246
238
  def get_meta_value(self, meta: Dict[str, str], key: str) -> str:
247
239
  """
@@ -257,7 +249,13 @@ class IpWare(IpWareMeta, IpWareProxy, IpWareIpAddress):
257
249
  Given a list of keys, it returns a list of cleaned up values
258
250
  @return: a list of values
259
251
  """
260
- return [self.get_meta_value(meta, key) for key in self.precedence]
252
+ meta_list: List[str] = []
253
+ for key in self.precedence:
254
+ value = self.get_meta_value(meta, key).strip()
255
+ if value:
256
+ meta_list.append(value)
257
+
258
+ return meta_list
261
259
 
262
260
  def get_client_ip(
263
261
  self,
@@ -272,8 +270,6 @@ class IpWare(IpWareMeta, IpWareProxy, IpWareIpAddress):
272
270
  private_list: List[OptionalIpAddressType] = []
273
271
 
274
272
  for ip_str in self.get_meta_values(meta):
275
- if not ip_str:
276
- continue
277
273
 
278
274
  ip_list = self.get_ips_from_string(ip_str)
279
275
  if not ip_list:
@@ -337,7 +333,11 @@ class IpWare(IpWareMeta, IpWareProxy, IpWareIpAddress):
337
333
  return best_client_ip, True
338
334
 
339
335
  # the incoming ips match our proxy count
340
- if self.proxy_count > 0 and proxy_count_validated:
336
+ if (
337
+ self.proxy_count is not None
338
+ and self.proxy_count > 0
339
+ and proxy_count_validated
340
+ ):
341
341
  best_client_ip_index = self.proxy_count + 1
342
342
  best_client_ip = ip_list[-best_client_ip_index]
343
343
  return best_client_ip, True
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-ipware
3
- Version: 2.0.3
3
+ Version: 2.0.4
4
4
  Summary: A Python package to retrieve user's IP address
5
5
  Author-email: Val Neekman <info@neekware.com>
6
6
  License: MIT
@@ -216,23 +216,41 @@ If your python server is behind a `known` number of proxies, but you deploy on m
216
216
  You can customize the proxy count by providing your `proxy_count` during initialization when calling `IpWare(proxy_count=2)`.
217
217
 
218
218
  ```python
219
- # In the above scenario, the total number of proxies can be used as a way to filter out unwanted requests.
220
219
  from python_ipware import IpWare
221
220
 
222
- # enforce proxy count
223
- ipw = IpWare(proxy_count=1)
221
+ # Enforce proxy count
222
+ # proxy_count=0 is valid
223
+ # proxy_count=None to disable proxy_count check
224
+ ipw = IpWare(proxy_count=2)
224
225
 
225
- # enforce proxy count and trusted proxies
226
- ipw = IpWare(proxy_count=1, proxy_list=["198.84.193.157"])
226
+ # Example usage in non-strict mode:
227
+ # X-Forwarded-For format: <fake>, <client>, <proxy1>, <proxy2>
228
+ # At least `proxy_count` number of proxies
229
+ ip, trusted_route = ipw.get_client_ip(meta=request.META)
227
230
 
231
+ # Example usage in strict mode:
232
+ # X-Forwarded-For format: <client>, <proxy1>, <proxy2>
233
+ # Exact `proxy_count` number of proxies
234
+ ip, trusted_route = ipw.get_client_ip(meta=request.META, strict=True)
235
+ ```
228
236
 
229
- # usage: non-strict mode (X-Forwarded-For: <fake>, <client>, <proxy1>, <proxy2>)
230
- # total number of ip addresses are greater than the total count
231
- ip, trusted_route = ipw.get_client_ip(meta=request.META)
237
+ ### Proxy Count & Trusted Proxy List Combo
238
+ In this example, we utilize the total number of proxies as a method to filter out unwanted requests while verifying the trust proxies.
232
239
 
240
+ ```python
241
+ from python_ipware import IpWare
233
242
 
234
- # usage: strict mode (X-Forwarded-For: <client>, <proxy1>, <proxy2>)
235
- # total number of ip addresses are exactly equal to client ip + proxy_count
243
+ # Enforce both proxy count and trusted proxies
244
+ ipw = IpWare(proxy_count=1, proxy_list=["198.84.193.157"])
245
+
246
+ # Example usage in non-strict mode:
247
+ # X-Forwarded-For format: <fake>, <client>, <proxy1>, <proxy2>
248
+ # At least `proxy_count` number of proxies
249
+ ip, trusted_route = ipw.get_client_ip(meta=request.META)
250
+
251
+ # Example usage in strict mode:
252
+ # X-Forwarded-For format: <client>, <proxy1>
253
+ # Exact `proxy_count` number of proxies
236
254
  ip, trusted_route = ipw.get_client_ip(meta=request.META, strict=True)
237
255
  ```
238
256
 
@@ -175,39 +175,69 @@ class TestIPv4Common(unittest.TestCase):
175
175
  class TestIPv4ProxyCount(unittest.TestCase):
176
176
  """IPv4 Proxy Count Test"""
177
177
 
178
- def setUp(self):
179
- self.ipware = IpWare(proxy_count=1)
180
-
181
- def tearDown(self):
182
- self.ipware = None
183
-
184
- def test_singleton_proxy_count(self):
178
+ def test_proxy_count_one_missing_proxy_fail(self):
179
+ ipware = IpWare(proxy_count=1)
185
180
  meta = {
186
181
  "HTTP_X_FORWARDED_FOR": "177.139.233.139",
187
182
  }
188
- r = self.ipware.get_client_ip(meta)
183
+ r = ipware.get_client_ip(meta)
184
+
189
185
  self.assertEqual(r, (None, False))
190
186
 
191
- def test_singleton_proxy_count_private(self):
187
+ def test_proxy_count_one_at_least_one_proxy_pass(self):
188
+ ipware = IpWare(proxy_count=1)
192
189
  meta = {
193
- "HTTP_X_FORWARDED_FOR": "10.0.0.0",
194
- "HTTP_X_REAL_IP": "177.139.233.139",
190
+ "HTTP_X_FORWARDED_FOR": "177.139.233.139, 198.84.193.157, 198.84.193.158",
195
191
  }
196
- r = self.ipware.get_client_ip(meta)
192
+ r = ipware.get_client_ip(meta)
193
+ self.assertEqual(r, (IPv4Address("198.84.193.157"), True))
194
+
195
+ def test_proxy_count_one_exactly_one_proxy_fail(self):
196
+ ipware = IpWare(proxy_count=1)
197
+ meta = {
198
+ "HTTP_X_FORWARDED_FOR": "177.139.233.139, 198.84.193.157, 198.84.193.158",
199
+ }
200
+ r = ipware.get_client_ip(meta, strict=True)
197
201
  self.assertEqual(r, (None, False))
198
202
 
199
- def test_proxy_count_relax(self):
203
+ def test_proxy_count_one_exactly_one_proxy_pass(self):
204
+ ipware = IpWare(proxy_count=1)
205
+ meta = {
206
+ "HTTP_X_FORWARDED_FOR": "177.139.233.139, 198.84.193.157",
207
+ }
208
+ r = ipware.get_client_ip(meta, strict=True)
209
+ self.assertEqual(r, (IPv4Address("177.139.233.139"), True))
210
+
211
+ def test_proxy_count_one_dont_care_proxy_pass(self):
212
+ ipware = IpWare()
200
213
  meta = {
201
214
  "HTTP_X_FORWARDED_FOR": "177.139.233.139, 198.84.193.157, 198.84.193.158",
202
215
  }
203
- r = self.ipware.get_client_ip(meta, strict=False)
204
- self.assertEqual(r, (IPv4Address("198.84.193.157"), True))
216
+ r = ipware.get_client_ip(meta)
217
+ self.assertEqual(r, (IPv4Address("177.139.233.139"), False))
205
218
 
206
- def test_proxy_count_strict(self):
219
+ def test_proxy_count_zero_dont_care_proxy_pass(self):
220
+ ipware = IpWare(proxy_count=0)
207
221
  meta = {
208
- "HTTP_X_FORWARDED_FOR": "177.139.233.138, 177.139.233.139, 198.84.193.158",
222
+ "HTTP_X_FORWARDED_FOR": "177.139.233.139, 198.84.193.157, 198.84.193.158",
209
223
  }
210
- r = self.ipware.get_client_ip(meta, strict=True)
224
+ r = ipware.get_client_ip(meta)
225
+ self.assertEqual(r, (IPv4Address("177.139.233.139"), False))
226
+
227
+ def test_proxy_count_zero_exact_zero_proxy_pass(self):
228
+ ipware = IpWare(proxy_count=0)
229
+ meta = {
230
+ "HTTP_X_FORWARDED_FOR": "177.139.233.139",
231
+ }
232
+ r = ipware.get_client_ip(meta, strict=True)
233
+ self.assertEqual(r, (IPv4Address("177.139.233.139"), False))
234
+
235
+ def test_proxy_count_zero_exact_zero_proxy_fail(self):
236
+ ipware = IpWare(proxy_count=0)
237
+ meta = {
238
+ "HTTP_X_FORWARDED_FOR": "177.139.233.139, 198.84.193.157, 198.84.193.158",
239
+ }
240
+ r = ipware.get_client_ip(meta, strict=True)
211
241
  self.assertEqual(r, (None, False))
212
242
 
213
243
 
@@ -245,26 +275,68 @@ class TestIPv4ProxyList(unittest.TestCase):
245
275
  class TestIPv4ProxyCountProxyList(unittest.TestCase):
246
276
  """IPv4 Proxy Count Test"""
247
277
 
248
- def setUp(self):
249
- self.ipware = IpWare(
250
- proxy_count=2, proxy_list=["198.84.193.157", "198.84.193.158"]
251
- )
278
+ def test_proxy_list_relax(self):
279
+ ipware = IpWare(proxy_list=["198.84.193.157", "198.84.193.158"])
280
+ meta = {
281
+ "HTTP_X_FORWARDED_FOR": "177.139.233.138, 177.139.233.139, 198.84.193.157, 198.84.193.158",
282
+ }
283
+ r = ipware.get_client_ip(meta)
284
+ self.assertEqual(r, (IPv4Address("177.139.233.139"), True))
252
285
 
253
- def tearDown(self):
254
- self.ipware = None
286
+ def test_proxy_list_strict_pass(self):
287
+ ipware = IpWare(proxy_list=["198.84.193.157", "198.84.193.158"])
288
+ meta = {
289
+ "HTTP_X_FORWARDED_FOR": "177.139.233.139, 198.84.193.157, 198.84.193.158",
290
+ }
291
+ r = ipware.get_client_ip(meta, strict=True)
292
+ self.assertEqual(r, (IPv4Address("177.139.233.139"), True))
255
293
 
256
- def test_proxy_list_relax(self):
294
+ def test_proxy_list_strict_fail(self):
295
+ ipware = IpWare(proxy_list=["198.84.193.157", "198.84.193.158"])
257
296
  meta = {
258
297
  "HTTP_X_FORWARDED_FOR": "177.139.233.138, 177.139.233.139, 198.84.193.157, 198.84.193.158",
259
298
  }
260
- r = self.ipware.get_client_ip(meta)
299
+ r = ipware.get_client_ip(meta, strict=True)
300
+ self.assertEqual(r, (None, False))
301
+
302
+ def test_proxy_list_relax_exact_pass(self):
303
+ ipware = IpWare(proxy_count=2, proxy_list=["198.84.193.157", "198.84.193.158"])
304
+ meta = {
305
+ "HTTP_X_FORWARDED_FOR": "177.139.233.138, 177.139.233.139, 198.84.193.157, 198.84.193.158",
306
+ }
307
+ r = ipware.get_client_ip(meta)
261
308
  self.assertEqual(r, (IPv4Address("177.139.233.139"), True))
262
309
 
263
- def test_proxy_list_strict(self):
310
+ def test_proxy_list_relax_count_under_pass(self):
311
+ ipware = IpWare(proxy_count=1, proxy_list=["198.84.193.157", "198.84.193.158"])
264
312
  meta = {
265
313
  "HTTP_X_FORWARDED_FOR": "177.139.233.138, 177.139.233.139, 198.84.193.157, 198.84.193.158",
266
314
  }
267
- r = self.ipware.get_client_ip(meta, strict=True)
315
+ r = ipware.get_client_ip(meta)
316
+ self.assertEqual(r, (IPv4Address("177.139.233.139"), True))
317
+
318
+ def test_proxy_list_relax_count_over_pass(self):
319
+ ipware = IpWare(proxy_count=5, proxy_list=["198.84.193.157", "198.84.193.158"])
320
+ meta = {
321
+ "HTTP_X_FORWARDED_FOR": "177.139.233.138, 177.139.233.139, 198.84.193.157, 198.84.193.158",
322
+ }
323
+ r = ipware.get_client_ip(meta)
324
+ self.assertEqual(r, (None, False))
325
+
326
+ def test_proxy_list_count_exact_pass(self):
327
+ ipware = IpWare(proxy_count=2, proxy_list=["198.84.193.157", "198.84.193.158"])
328
+ meta = {
329
+ "HTTP_X_FORWARDED_FOR": "177.139.233.138, 177.139.233.139, 198.84.193.157, 198.84.193.158",
330
+ }
331
+ r = ipware.get_client_ip(meta)
332
+ self.assertEqual(r, (IPv4Address("177.139.233.139"), True))
333
+
334
+ def test_proxy_list_count_exact_fail(self):
335
+ ipware = IpWare(proxy_count=4, proxy_list=["198.84.193.157", "198.84.193.158"])
336
+ meta = {
337
+ "HTTP_X_FORWARDED_FOR": "177.139.233.138, 177.139.233.139, 198.84.193.157, 198.84.193.158",
338
+ }
339
+ r = ipware.get_client_ip(meta)
268
340
  self.assertEqual(r, (None, False))
269
341
 
270
342
 
@@ -1 +0,0 @@
1
- __version__ = "2.0.3"
File without changes
File without changes