tplinkrouterc6u 5.12.4__tar.gz → 5.13.0__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.
- {tplinkrouterc6u-5.12.4/tplinkrouterc6u.egg-info → tplinkrouterc6u-5.13.0}/PKG-INFO +10 -2
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/README.md +9 -1
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/setup.py +1 -1
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/test/test_client_c6u.py +52 -19
- tplinkrouterc6u-5.13.0/test/test_client_c6u_v1_11.py +95 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/test/test_client_ex.py +80 -0
- tplinkrouterc6u-5.13.0/test/test_client_r.py +633 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/test/test_client_xdr.py +5 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/__init__.py +2 -1
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/client/c6u.py +97 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/client/ex.py +9 -11
- tplinkrouterc6u-5.13.0/tplinkrouterc6u/client/r.py +198 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/client/xdr.py +10 -1
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/provider.py +4 -1
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0/tplinkrouterc6u.egg-info}/PKG-INFO +10 -2
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u.egg-info/SOURCES.txt +3 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/LICENSE +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/setup.cfg +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/test/__init__.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/test/test_client_c1200.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/test/test_client_c80.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/test/test_client_deco.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/test/test_client_mr.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/test/test_client_mr_200.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/test/test_client_re330.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/test/test_client_vr400v2.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/test/test_client_wdr.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/client/__init__.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/client/c1200.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/client/c5400x.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/client/c80.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/client/deco.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/client/mr.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/client/mr200.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/client/re330.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/client/vr.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/client/vr400v2.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/client/wdr.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/client_abstract.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/common/__init__.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/common/dataclass.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/common/encryption.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/common/exception.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/common/helper.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u/common/package_enum.py +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u.egg-info/dependency_links.txt +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u.egg-info/requires.txt +0 -0
- {tplinkrouterc6u-5.12.4 → tplinkrouterc6u-5.13.0}/tplinkrouterc6u.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tplinkrouterc6u
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.13.0
|
|
4
4
|
Summary: TP-Link Router API (supports also Mercusys Router)
|
|
5
5
|
Home-page: https://github.com/AlexandrErohin/TP-Link-Archer-C6U
|
|
6
6
|
Author: Alex Erohin
|
|
@@ -56,6 +56,7 @@ Python package for API access and management for TP-Link and Mercusys Routers. S
|
|
|
56
56
|
```python
|
|
57
57
|
from tplinkrouterc6u import (
|
|
58
58
|
TplinkRouterProvider,
|
|
59
|
+
TplinkRouterV1_11,
|
|
59
60
|
TplinkRouter,
|
|
60
61
|
TplinkC1200Router,
|
|
61
62
|
TplinkC5400XRouter,
|
|
@@ -66,6 +67,7 @@ from tplinkrouterc6u import (
|
|
|
66
67
|
TPLinkVR400v2Client,
|
|
67
68
|
TPLinkEXClient, # Class for EX series routers which supports old firmwares with AES cipher CBC mode
|
|
68
69
|
TPLinkEXClientGCM, # Class for EX series routers which supports AES cipher GCM mode
|
|
70
|
+
TPLinkRClient,
|
|
69
71
|
TPLinkXDRClient,
|
|
70
72
|
TPLinkDecoClient,
|
|
71
73
|
TplinkC80Router,
|
|
@@ -83,7 +85,7 @@ router = TplinkRouterProvider.get_client('http://192.168.0.1', 'password')
|
|
|
83
85
|
# If you have the TP-link C5400X or similar, you can use the TplinkC5400XRouter class instead of the TplinkRouter class.
|
|
84
86
|
# Remember that the password for this router is different, here you need to use the web encrypted password.
|
|
85
87
|
# To get web encrypted password, read Web Encrypted Password section
|
|
86
|
-
# router = TplinkC5400XRouter('http://192.168.0.1','WebEncryptedPassword', Logger('test'))
|
|
88
|
+
# router = TplinkC5400XRouter('http://192.168.0.1','WebEncryptedPassword', logger: Logger('test'))
|
|
87
89
|
|
|
88
90
|
try:
|
|
89
91
|
router.authorize() # authorizing
|
|
@@ -380,7 +382,10 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
|
|
|
380
382
|
- Deco XE75PRO (v3.0)
|
|
381
383
|
- EX511 v2.0
|
|
382
384
|
- HX510 v1.0
|
|
385
|
+
- M8550 v1
|
|
386
|
+
- NE200-Outdoor v1.0
|
|
383
387
|
- NX510v v1.0
|
|
388
|
+
- NX600 v2.0
|
|
384
389
|
- TD-W9960 (v1, V1.20)
|
|
385
390
|
- TL-MR100 v2.0
|
|
386
391
|
- TL-MR105
|
|
@@ -389,10 +394,13 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
|
|
|
389
394
|
- TL-MR150 v2
|
|
390
395
|
- TL-MR6400 (v5, v5.3)
|
|
391
396
|
- TL-MR6500v
|
|
397
|
+
- TL-R470GP-AC 4.0
|
|
398
|
+
- TL-R488GPM-AC 2.0
|
|
392
399
|
- TL-WA1201 3.0
|
|
393
400
|
- TL-WA3001 v1.0
|
|
394
401
|
- TL-XDR3010 V2
|
|
395
402
|
- TL-WDR3600 V1
|
|
403
|
+
- TL-XDR5410 1.0
|
|
396
404
|
- TL-XDR6088 v1.0.30
|
|
397
405
|
- VX420-G2h v1.1
|
|
398
406
|
- VX800v v1
|
|
@@ -23,6 +23,7 @@ Python package for API access and management for TP-Link and Mercusys Routers. S
|
|
|
23
23
|
```python
|
|
24
24
|
from tplinkrouterc6u import (
|
|
25
25
|
TplinkRouterProvider,
|
|
26
|
+
TplinkRouterV1_11,
|
|
26
27
|
TplinkRouter,
|
|
27
28
|
TplinkC1200Router,
|
|
28
29
|
TplinkC5400XRouter,
|
|
@@ -33,6 +34,7 @@ from tplinkrouterc6u import (
|
|
|
33
34
|
TPLinkVR400v2Client,
|
|
34
35
|
TPLinkEXClient, # Class for EX series routers which supports old firmwares with AES cipher CBC mode
|
|
35
36
|
TPLinkEXClientGCM, # Class for EX series routers which supports AES cipher GCM mode
|
|
37
|
+
TPLinkRClient,
|
|
36
38
|
TPLinkXDRClient,
|
|
37
39
|
TPLinkDecoClient,
|
|
38
40
|
TplinkC80Router,
|
|
@@ -50,7 +52,7 @@ router = TplinkRouterProvider.get_client('http://192.168.0.1', 'password')
|
|
|
50
52
|
# If you have the TP-link C5400X or similar, you can use the TplinkC5400XRouter class instead of the TplinkRouter class.
|
|
51
53
|
# Remember that the password for this router is different, here you need to use the web encrypted password.
|
|
52
54
|
# To get web encrypted password, read Web Encrypted Password section
|
|
53
|
-
# router = TplinkC5400XRouter('http://192.168.0.1','WebEncryptedPassword', Logger('test'))
|
|
55
|
+
# router = TplinkC5400XRouter('http://192.168.0.1','WebEncryptedPassword', logger: Logger('test'))
|
|
54
56
|
|
|
55
57
|
try:
|
|
56
58
|
router.authorize() # authorizing
|
|
@@ -347,7 +349,10 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
|
|
|
347
349
|
- Deco XE75PRO (v3.0)
|
|
348
350
|
- EX511 v2.0
|
|
349
351
|
- HX510 v1.0
|
|
352
|
+
- M8550 v1
|
|
353
|
+
- NE200-Outdoor v1.0
|
|
350
354
|
- NX510v v1.0
|
|
355
|
+
- NX600 v2.0
|
|
351
356
|
- TD-W9960 (v1, V1.20)
|
|
352
357
|
- TL-MR100 v2.0
|
|
353
358
|
- TL-MR105
|
|
@@ -356,10 +361,13 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
|
|
|
356
361
|
- TL-MR150 v2
|
|
357
362
|
- TL-MR6400 (v5, v5.3)
|
|
358
363
|
- TL-MR6500v
|
|
364
|
+
- TL-R470GP-AC 4.0
|
|
365
|
+
- TL-R488GPM-AC 2.0
|
|
359
366
|
- TL-WA1201 3.0
|
|
360
367
|
- TL-WA3001 v1.0
|
|
361
368
|
- TL-XDR3010 V2
|
|
362
369
|
- TL-WDR3600 V1
|
|
370
|
+
- TL-XDR5410 1.0
|
|
363
371
|
- TL-XDR6088 v1.0.30
|
|
364
372
|
- VX420-G2h v1.1
|
|
365
373
|
- VX800v v1
|
|
@@ -14,6 +14,12 @@ from tplinkrouterc6u import (
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class TestTPLinkClient(TestCase):
|
|
17
|
+
router_class = TplinkRouter
|
|
18
|
+
game_accelerator_path = 'admin/smart_network?form=game_accelerator'
|
|
19
|
+
openvpn_config_path = 'admin/openvpn?form=config'
|
|
20
|
+
pptpd_config_path = 'admin/pptpd?form=config'
|
|
21
|
+
vpn_uses_data_param = True
|
|
22
|
+
|
|
17
23
|
def test_get_status(self) -> None:
|
|
18
24
|
response_status = '''
|
|
19
25
|
{
|
|
@@ -211,7 +217,9 @@ class TestTPLinkClient(TestCase):
|
|
|
211
217
|
}
|
|
212
218
|
'''
|
|
213
219
|
|
|
214
|
-
|
|
220
|
+
router_class = self.router_class
|
|
221
|
+
|
|
222
|
+
class TPLinkRouterTest(router_class):
|
|
215
223
|
def request(self, path: str, data: str,
|
|
216
224
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
217
225
|
if path == 'admin/status?form=all&operation=read':
|
|
@@ -339,7 +347,9 @@ class TestTPLinkClient(TestCase):
|
|
|
339
347
|
}
|
|
340
348
|
'''
|
|
341
349
|
|
|
342
|
-
|
|
350
|
+
router_class = self.router_class
|
|
351
|
+
|
|
352
|
+
class TPLinkRouterTest(router_class):
|
|
343
353
|
def request(self, path: str, data: str,
|
|
344
354
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
345
355
|
if path == 'admin/status?form=all&operation=read':
|
|
@@ -484,12 +494,15 @@ class TestTPLinkClient(TestCase):
|
|
|
484
494
|
}
|
|
485
495
|
'''
|
|
486
496
|
|
|
487
|
-
|
|
497
|
+
router_class = self.router_class
|
|
498
|
+
game_accelerator_path = self.game_accelerator_path
|
|
499
|
+
|
|
500
|
+
class TPLinkRouterTest(router_class):
|
|
488
501
|
def request(self, path: str, data: str,
|
|
489
502
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
490
503
|
if path == 'admin/status?form=all&operation=read':
|
|
491
504
|
return loads(response_status)['data']
|
|
492
|
-
elif path ==
|
|
505
|
+
elif path == game_accelerator_path:
|
|
493
506
|
return loads(response_game_accelerator)['data']
|
|
494
507
|
elif path == 'admin/wireless?form=statistics':
|
|
495
508
|
return loads(response_stats)['data']
|
|
@@ -618,7 +631,9 @@ class TestTPLinkClient(TestCase):
|
|
|
618
631
|
}
|
|
619
632
|
'''
|
|
620
633
|
|
|
621
|
-
|
|
634
|
+
router_class = self.router_class
|
|
635
|
+
|
|
636
|
+
class TPLinkRouterTest(router_class):
|
|
622
637
|
def request(self, path: str, data: str,
|
|
623
638
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
624
639
|
if path == 'admin/status?form=all&operation=read':
|
|
@@ -661,8 +676,9 @@ class TestTPLinkClient(TestCase):
|
|
|
661
676
|
def test_set_wifi(self) -> None:
|
|
662
677
|
check_url = ''
|
|
663
678
|
check_data = ''
|
|
679
|
+
router_class = self.router_class
|
|
664
680
|
|
|
665
|
-
class TPLinkRouterTest(
|
|
681
|
+
class TPLinkRouterTest(router_class):
|
|
666
682
|
def request(self, path: str, data: str,
|
|
667
683
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
668
684
|
nonlocal check_url, check_data
|
|
@@ -705,8 +721,9 @@ class TestTPLinkClient(TestCase):
|
|
|
705
721
|
|
|
706
722
|
def test_get_ipv4_status_empty(self) -> None:
|
|
707
723
|
response_network = '{"result": {}, "error_code": 0}'
|
|
724
|
+
router_class = self.router_class
|
|
708
725
|
|
|
709
|
-
class TPLinkRouterTest(
|
|
726
|
+
class TPLinkRouterTest(router_class):
|
|
710
727
|
def request(self, path: str, data: str,
|
|
711
728
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
712
729
|
if path == 'admin/network?form=status_ipv4&operation=read':
|
|
@@ -750,8 +767,9 @@ class TestTPLinkClient(TestCase):
|
|
|
750
767
|
"operator": "load"
|
|
751
768
|
}
|
|
752
769
|
'''
|
|
770
|
+
router_class = self.router_class
|
|
753
771
|
|
|
754
|
-
class TPLinkRouterTest(
|
|
772
|
+
class TPLinkRouterTest(router_class):
|
|
755
773
|
def request(self, path: str, data: str,
|
|
756
774
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
757
775
|
if path == 'admin/status?form=all&operation=read':
|
|
@@ -800,8 +818,9 @@ class TestTPLinkClient(TestCase):
|
|
|
800
818
|
}
|
|
801
819
|
}
|
|
802
820
|
'''
|
|
821
|
+
router_class = self.router_class
|
|
803
822
|
|
|
804
|
-
class TPLinkRouterTest(
|
|
823
|
+
class TPLinkRouterTest(router_class):
|
|
805
824
|
def request(self, path: str, data: str,
|
|
806
825
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
807
826
|
if path == 'admin/status?form=all&operation=read':
|
|
@@ -871,7 +890,12 @@ class TestTPLinkClient(TestCase):
|
|
|
871
890
|
"extra": "7450", "vpntype": "pptp", "key": "7450"}
|
|
872
891
|
]"""
|
|
873
892
|
|
|
874
|
-
|
|
893
|
+
router_class = self.router_class
|
|
894
|
+
openvpn_config_path = self.openvpn_config_path
|
|
895
|
+
pptpd_config_path = self.pptpd_config_path
|
|
896
|
+
vpn_uses_data_param = self.vpn_uses_data_param
|
|
897
|
+
|
|
898
|
+
class TPLinkRouterTest(router_class):
|
|
875
899
|
def request(
|
|
876
900
|
self,
|
|
877
901
|
path: str,
|
|
@@ -879,14 +903,20 @@ class TestTPLinkClient(TestCase):
|
|
|
879
903
|
ignore_response: bool = False,
|
|
880
904
|
ignore_errors: bool = False,
|
|
881
905
|
) -> dict | None:
|
|
882
|
-
if path ==
|
|
906
|
+
if path == openvpn_config_path:
|
|
883
907
|
return loads(response_openvpn_read)
|
|
884
|
-
if path ==
|
|
908
|
+
if path == pptpd_config_path:
|
|
885
909
|
return loads(response_pptp_read)
|
|
886
|
-
if
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
910
|
+
if vpn_uses_data_param:
|
|
911
|
+
if path == "admin/vpnconn?form=config" and data == "operation=list&vpntype=openvpn":
|
|
912
|
+
return loads(respone_vpnconn_openvpn)
|
|
913
|
+
if path == "admin/vpnconn?form=config" and data == "operation=list&vpntype=pptp":
|
|
914
|
+
return loads(respone_vpnconn_pptpvpn)
|
|
915
|
+
else:
|
|
916
|
+
if path == "admin/vpnconn?form=config&operation=list&vpntype=openvpn":
|
|
917
|
+
return loads(respone_vpnconn_openvpn)
|
|
918
|
+
if path == "admin/vpnconn?form=config&operation=list&vpntype=pptp":
|
|
919
|
+
return loads(respone_vpnconn_pptpvpn)
|
|
890
920
|
raise ClientException()
|
|
891
921
|
|
|
892
922
|
client = TPLinkRouterTest("", "")
|
|
@@ -910,7 +940,10 @@ class TestTPLinkClient(TestCase):
|
|
|
910
940
|
}
|
|
911
941
|
"""
|
|
912
942
|
|
|
913
|
-
|
|
943
|
+
router_class = self.router_class
|
|
944
|
+
openvpn_config_path = self.openvpn_config_path
|
|
945
|
+
|
|
946
|
+
class TPLinkRouterTest(router_class):
|
|
914
947
|
def request(
|
|
915
948
|
self,
|
|
916
949
|
path: str,
|
|
@@ -918,7 +951,7 @@ class TestTPLinkClient(TestCase):
|
|
|
918
951
|
ignore_response: bool = False,
|
|
919
952
|
ignore_errors: bool = False,
|
|
920
953
|
) -> dict | None:
|
|
921
|
-
if path ==
|
|
954
|
+
if path == openvpn_config_path and data == "operation=read":
|
|
922
955
|
return loads(response_openvpn_read)
|
|
923
956
|
self.captured_path = path
|
|
924
957
|
self.captured_data = data
|
|
@@ -930,7 +963,7 @@ class TestTPLinkClient(TestCase):
|
|
|
930
963
|
"operation=write&enabled=on"
|
|
931
964
|
"&proto=udp&access=home&cert_exist=True&mask=255.255.255.0&port=1194&serverip=10.8.0.0"
|
|
932
965
|
)
|
|
933
|
-
self.assertEqual(client.captured_path,
|
|
966
|
+
self.assertEqual(client.captured_path, self.openvpn_config_path)
|
|
934
967
|
self.assertEqual(client.captured_data, expected_data)
|
|
935
968
|
|
|
936
969
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
from unittest import main
|
|
2
|
+
from unittest.mock import patch, Mock
|
|
3
|
+
from test_client_c6u import TestTPLinkClient
|
|
4
|
+
from tplinkrouterc6u import TplinkRouterV1_11, ClientException
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TestTPLinkClientV1_11(TestTPLinkClient):
|
|
8
|
+
"""Inherits all tests from TestTPLinkClient, using TplinkRouterV1_11."""
|
|
9
|
+
|
|
10
|
+
router_class = TplinkRouterV1_11
|
|
11
|
+
game_accelerator_path = 'admin/smart_network?form=game_accelerator&operation=loadDevice'
|
|
12
|
+
openvpn_config_path = 'admin/openvpn?form=config&operation=read'
|
|
13
|
+
pptpd_config_path = 'admin/pptpd?form=config&operation=read'
|
|
14
|
+
vpn_uses_data_param = False
|
|
15
|
+
|
|
16
|
+
# V1_11-specific tests only
|
|
17
|
+
|
|
18
|
+
def test_supports_password_too_long(self) -> None:
|
|
19
|
+
long_password = 'a' * 126
|
|
20
|
+
client = TplinkRouterV1_11('http://192.168.0.1', long_password)
|
|
21
|
+
self.assertFalse(client.supports())
|
|
22
|
+
|
|
23
|
+
@patch('tplinkrouterc6u.client.c6u.EncryptionWrapper.rsa_encrypt')
|
|
24
|
+
@patch('tplinkrouterc6u.client.c6u.post')
|
|
25
|
+
def test_authorize_success(self, mock_post: Mock, mock_rsa: Mock) -> None:
|
|
26
|
+
mock_rsa.return_value = 'encrypted_password_hex'
|
|
27
|
+
|
|
28
|
+
keys_response = Mock()
|
|
29
|
+
keys_response.json.return_value = {
|
|
30
|
+
'success': True,
|
|
31
|
+
'data': {
|
|
32
|
+
'password': ['mock_nn_value', '010001']
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
login_response = Mock()
|
|
37
|
+
login_response.json.return_value = {
|
|
38
|
+
'success': True,
|
|
39
|
+
'data': {
|
|
40
|
+
'stok': 'test_stok_12345'
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
login_response.headers = {'set-cookie': 'sysauth=test_sysauth_cookie; path=/'}
|
|
44
|
+
|
|
45
|
+
mock_post.side_effect = [keys_response, login_response]
|
|
46
|
+
|
|
47
|
+
client = TplinkRouterV1_11('http://192.168.0.1', 'testpassword')
|
|
48
|
+
client.authorize()
|
|
49
|
+
|
|
50
|
+
self.assertTrue(client._logged)
|
|
51
|
+
self.assertEqual(client._stok, 'test_stok_12345')
|
|
52
|
+
self.assertEqual(client._sysauth, 'test_sysauth_cookie')
|
|
53
|
+
self.assertEqual(mock_post.call_count, 2)
|
|
54
|
+
|
|
55
|
+
first_call = mock_post.call_args_list[0]
|
|
56
|
+
self.assertIn('login?form=keys', first_call[0][0])
|
|
57
|
+
|
|
58
|
+
second_call = mock_post.call_args_list[1]
|
|
59
|
+
self.assertIn('login?form=login', second_call[0][0])
|
|
60
|
+
login_data = second_call[1]['data']
|
|
61
|
+
self.assertTrue(login_data.startswith('operation=login&password='))
|
|
62
|
+
|
|
63
|
+
@patch('tplinkrouterc6u.client.c6u.EncryptionWrapper.rsa_encrypt')
|
|
64
|
+
@patch('tplinkrouterc6u.client.c6u.post')
|
|
65
|
+
def test_authorize_failure(self, mock_post: Mock, mock_rsa: Mock) -> None:
|
|
66
|
+
mock_rsa.return_value = 'encrypted_password_hex'
|
|
67
|
+
|
|
68
|
+
keys_response = Mock()
|
|
69
|
+
keys_response.json.return_value = {
|
|
70
|
+
'success': True,
|
|
71
|
+
'data': {
|
|
72
|
+
'password': ['mock_nn_value', '010001']
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
login_response = Mock()
|
|
77
|
+
login_response.json.return_value = {
|
|
78
|
+
'success': False,
|
|
79
|
+
'data': {'errorcode': 'invalid password'}
|
|
80
|
+
}
|
|
81
|
+
login_response.headers = {}
|
|
82
|
+
|
|
83
|
+
mock_post.side_effect = [keys_response, login_response]
|
|
84
|
+
|
|
85
|
+
client = TplinkRouterV1_11('http://192.168.0.1', 'wrongpassword')
|
|
86
|
+
|
|
87
|
+
with self.assertRaises(ClientException) as context:
|
|
88
|
+
client.authorize()
|
|
89
|
+
|
|
90
|
+
self.assertIn('Login failed', str(context.exception))
|
|
91
|
+
self.assertFalse(client._logged)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
if __name__ == '__main__':
|
|
95
|
+
main()
|
|
@@ -204,6 +204,86 @@ class TestTPLinkEXClient(TestCase):
|
|
|
204
204
|
self.assertEqual(status.devices[1].packets_sent, None) # TODO
|
|
205
205
|
self.assertEqual(status.devices[1].packets_received, None) # TODO
|
|
206
206
|
|
|
207
|
+
def test_get_status_NE200(self) -> None:
|
|
208
|
+
DEV2_ADT_LAN = ('{"data":[{"MACAddress":"a0:28:84:de:dd:5c","IPAddress":"192.168.4.1","stack":"1,0,0,0,0,0"}],'
|
|
209
|
+
'"operation":"gl","oid":"DEV2_ADT_LAN","success":true}')
|
|
210
|
+
DEV2_ADT_WAN = ('{"data":[{"enable":"1","MACAddr":"","connIPv4Address":"","connIPv4Gateway":""'
|
|
211
|
+
',"stack":"1,0,0,0,0,0"}],"operation":"gl","oid":"DEV2_ADT_WAN","success":true}')
|
|
212
|
+
DEV2_ADT_WIFI_COMMON = ('{"data":[],"operation":"gl",'
|
|
213
|
+
'"oid":"DEV2_ADT_WIFI_COMMON","success":true}')
|
|
214
|
+
DEV2_HOST_ENTRY = ('{"data":[{"active":"1","X_TP_LanConnType":"1","physAddress":"66-E2-02-BD-B5-1B",'
|
|
215
|
+
'"IPAddress":"192.168.30.10","hostName":"host1","stack":"1,0,0,0,0,0"},'
|
|
216
|
+
'{"active":"1","X_TP_LanConnType":"1","physAddress":"F4-A3-86-2D-41-B5",'
|
|
217
|
+
'"IPAddress":"192.168.30.11","hostName":"host2","stack":"2,0,0,0,0,0"}],"operation":"gl",'
|
|
218
|
+
'"oid":"DEV2_HOST_ENTRY","success":true}')
|
|
219
|
+
DEV2_MEM_STATUS = ('{"data":{"total":"192780","free":"78400","stack":"0,0,0,0,0,0"},"operation":"go",'
|
|
220
|
+
'"oid":"DEV2_MEM_STATUS","success":true}')
|
|
221
|
+
DEV2_PROC_STATUS = ('{"data":{"CPUUsage":"69","stack":"0,0,0,0,0,0"},"operation":"go",'
|
|
222
|
+
'"oid":"DEV2_PROC_STATUS","success":true}')
|
|
223
|
+
|
|
224
|
+
class TPLinkEXClientTest(TPLinkEXClient):
|
|
225
|
+
self._token = True
|
|
226
|
+
|
|
227
|
+
def _request(self, url, method='POST', data_str=None, encrypt=False):
|
|
228
|
+
if 'DEV2_ADT_LAN' in data_str:
|
|
229
|
+
return 200, DEV2_ADT_LAN
|
|
230
|
+
elif 'DEV2_ADT_WAN' in data_str:
|
|
231
|
+
return 200, DEV2_ADT_WAN
|
|
232
|
+
elif 'DEV2_ADT_WIFI_COMMON' in data_str:
|
|
233
|
+
return 200, DEV2_ADT_WIFI_COMMON
|
|
234
|
+
elif 'DEV2_HOST_ENTRY' in data_str:
|
|
235
|
+
return 200, DEV2_HOST_ENTRY
|
|
236
|
+
elif 'DEV2_MEM_STATUS' in data_str:
|
|
237
|
+
return 200, DEV2_MEM_STATUS
|
|
238
|
+
elif 'DEV2_PROC_STATUS' in data_str:
|
|
239
|
+
return 200, DEV2_PROC_STATUS
|
|
240
|
+
raise ClientException()
|
|
241
|
+
|
|
242
|
+
client = TPLinkEXClientTest('', '')
|
|
243
|
+
status = client.get_status()
|
|
244
|
+
|
|
245
|
+
self.assertIsInstance(status, Status)
|
|
246
|
+
self.assertEqual(status.wan_macaddr, None)
|
|
247
|
+
self.assertEqual(status.lan_macaddr, 'A0-28-84-DE-DD-5C')
|
|
248
|
+
self.assertIsInstance(status.lan_macaddress, EUI48)
|
|
249
|
+
self.assertEqual(status.wan_ipv4_addr, None)
|
|
250
|
+
self.assertEqual(status.lan_ipv4_addr, '192.168.4.1')
|
|
251
|
+
self.assertEqual(status.wan_ipv4_gateway, None)
|
|
252
|
+
self.assertEqual(status.wired_total, 0)
|
|
253
|
+
self.assertEqual(status.wifi_clients_total, 2)
|
|
254
|
+
self.assertEqual(status.guest_clients_total, 0)
|
|
255
|
+
self.assertEqual(status.clients_total, 2)
|
|
256
|
+
self.assertEqual(status.guest_2g_enable, None)
|
|
257
|
+
self.assertEqual(status.guest_5g_enable, None)
|
|
258
|
+
self.assertEqual(status.iot_2g_enable, None)
|
|
259
|
+
self.assertEqual(status.iot_5g_enable, None)
|
|
260
|
+
self.assertEqual(status.wifi_2g_enable, None)
|
|
261
|
+
self.assertEqual(status.wifi_5g_enable, None)
|
|
262
|
+
self.assertEqual(status.wan_ipv4_uptime, None)
|
|
263
|
+
self.assertGreaterEqual(status.mem_usage, 0)
|
|
264
|
+
self.assertLessEqual(status.mem_usage, 1)
|
|
265
|
+
self.assertGreaterEqual(status.cpu_usage, 0)
|
|
266
|
+
self.assertLessEqual(status.cpu_usage, 1)
|
|
267
|
+
self.assertEqual(len(status.devices), 2)
|
|
268
|
+
self.assertIsInstance(status.devices[0], Device)
|
|
269
|
+
self.assertEqual(status.devices[0].type, Connection.HOST_2G)
|
|
270
|
+
self.assertEqual(status.devices[0].macaddr, '66-E2-02-BD-B5-1B')
|
|
271
|
+
self.assertIsInstance(status.devices[0].macaddress, EUI48)
|
|
272
|
+
self.assertEqual(status.devices[0].ipaddr, '192.168.30.10')
|
|
273
|
+
self.assertIsInstance(status.devices[0].ipaddress, IPv4Address)
|
|
274
|
+
self.assertEqual(status.devices[0].hostname, 'host1')
|
|
275
|
+
self.assertEqual(status.devices[0].packets_sent, None)
|
|
276
|
+
self.assertEqual(status.devices[0].packets_received, None)
|
|
277
|
+
self.assertIsInstance(status.devices[1], Device)
|
|
278
|
+
self.assertEqual(status.devices[1].type, Connection.HOST_2G)
|
|
279
|
+
self.assertEqual(status.devices[1].macaddr, 'F4-A3-86-2D-41-B5')
|
|
280
|
+
self.assertIsInstance(status.devices[1].macaddress, EUI48)
|
|
281
|
+
self.assertEqual(status.devices[1].ipaddr, '192.168.30.11')
|
|
282
|
+
self.assertIsInstance(status.devices[1].ipaddress, IPv4Address)
|
|
283
|
+
self.assertEqual(status.devices[1].hostname, 'host2')
|
|
284
|
+
self.assertEqual(status.devices[1].packets_sent, None) # TODO
|
|
285
|
+
self.assertEqual(status.devices[1].packets_received, None) # TODO
|
|
286
|
+
|
|
207
287
|
def test_get_ipv4_reservations(self) -> None:
|
|
208
288
|
|
|
209
289
|
response = ('{"data":[{"enable":"1","chaddr":"bf:75:44:4c:dc:9e","yiaddr":"192.168.8.21",'
|