Skip to content

Commit 743cb4f

Browse files
Updated unit test for forthcoming user endpoint enhancements
1 parent 7f08193 commit 743cb4f

4 files changed

Lines changed: 163 additions & 10 deletions

File tree

docs/CONTRIBUTING.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,8 @@ any payload data to receive a valid response you must set this value to `[{}]`.
381381
- `status` : an integer that specifies the tests expected HTTPS status code (defaults to `200`)
382382
- `return` : an integer that specifies the tests expected API return code (defaults to `0`)
383383
- `resp_time` : a float that specifies the tests maximum response time expected from the API endpoint
384+
- `auth_payload` : a dictionary containing authentication payload values (typically `client-id` and `client-token`)
385+
to use with the corresponding request (defaults the username and password passed into the command)
384386

385387
- `post_tests` : A list of dictionary formatted test parameters for POST requests. If this endpoint does not support
386388
POST requests, you do not need to override this property. If this endpoint does support POST request, but does not require
@@ -390,6 +392,8 @@ any payload data to receive a valid response you must set this value to `[{}]`.
390392
- `status` : an integer that specifies the tests expected HTTPS status code (defaults to `200`)
391393
- `return` : an integer that specifies the tests expected API return code (defaults to `0`)
392394
- `resp_time` : a float that specifies the tests maximum response time expected from the API endpoint
395+
- `auth_payload` : a dictionary containing authentication payload values (typically `client-id` and `client-token`)
396+
to use with the corresponding request (defaults the username and password passed into the command)
393397

394398
- `put_tests` : A list of dictionary formatted test parameters for PUT requests. If this endpoint does not support
395399
PUT requests, you do not need to override this property. If this endpoint does support PUT request, but does not require
@@ -399,6 +403,8 @@ any payload data to receive a valid response you must set this value to `[{}]`.
399403
- `status` : an integer that specifies the tests expected HTTPS status code (defaults to `200`)
400404
- `return` : an integer that specifies the tests expected API return code (defaults to `0`)
401405
- `resp_time` : a float that specifies the tests maximum response time expected from the API endpoint
406+
- `auth_payload` : a dictionary containing authentication payload values (typically `client-id` and `client-token`)
407+
to use with the corresponding request (defaults the username and password passed into the command)
402408

403409
- `delete_tests` : A list of dictionary formatted test parameters for DELETE requests. If this endpoint does not support
404410
DELETE requests, you do not need to override this property. If this endpoint does support DELETE request, but does not require
@@ -408,6 +414,8 @@ any payload data to receive a valid response you must set this value to `[{}]`.
408414
- `status` : an integer that specifies the tests expected HTTPS status code (defaults to `200`)
409415
- `return` : an integer that specifies the tests expected API return code (defaults to `0`)
410416
- `resp_time` : a float that specifies the tests maximum response time expected from the API endpoint
417+
- `auth_payload` : a dictionary containing authentication payload values (typically `client-id` and `client-token`)
418+
to use with the corresponding request (defaults the username and password passed into the command)
411419

412420
- `get_responses` : A list of previously executed GET requests in a dictionary format. Failing responses will not be
413421
included.

tests/test_api_v1_user.py

Lines changed: 124 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,106 @@
11
import unit_test_framework
22

3+
34
class APIUnitTestUser(unit_test_framework.APIUnitTest):
45
url = "/api/v1/user"
56
get_tests = [{"name": "Read local users"}]
67
post_tests = [
78
{
89
"name": "Create local user",
10+
"resp_time": 2, # Allow a couple seconds for user database to be updated
911
"payload": {
10-
"disabled": True,
12+
"disabled": False,
1113
"username": "new_user",
1214
"password": "changeme",
1315
"descr": "NEW USER",
1416
"authorizedkeys": "test auth key",
1517
"ipsecpsk": "test psk",
16-
"expires": "11/22/2050"
18+
"expires": "11/22/2050",
19+
"priv": ["page-system-usermanager"]
1720
},
18-
"resp_time": 2 # Allow a couple seconds for user database to be updated
19-
}
21+
},
22+
{
23+
"name": "Create a disabled local user using the previously created local user",
24+
"resp_time": 2, # Allow a couple seconds for user database to be updated
25+
"auth_payload": {"client-id": "new_user", "client-token": "changeme"},
26+
"payload": {
27+
"disabled": True,
28+
"username": "disabled_user",
29+
"password": "changeme",
30+
},
31+
},
32+
{
33+
"name": "Check disabled user's inability to authenticate",
34+
"status": 401,
35+
"return": 3,
36+
"auth_payload": {"client-id": "disabled_user", "client-token": "changeme"},
37+
},
38+
{
39+
"name": "Check username requirement and login using created user",
40+
"status": 400,
41+
"return": 5000,
42+
},
43+
{
44+
"name": "Check username unique constraint",
45+
"status": 400,
46+
"return": 5002,
47+
"payload": {
48+
"username": "new_user"
49+
}
50+
},
51+
{
52+
"name": "Check username character constraint",
53+
"status": 400,
54+
"return": 5036,
55+
"payload": {
56+
"username": "!@#"
57+
}
58+
},
59+
{
60+
"name": "Check reserved username constraint",
61+
"status": 400,
62+
"return": 5037,
63+
"payload": {
64+
"username": "root"
65+
}
66+
},
67+
{
68+
"name": "Check username length constraint",
69+
"status": 400,
70+
"return": 5038,
71+
"payload": {
72+
"username": "THIS_USERNAME_IS_TOO_LONG_FOR_PFSENSE_TO_HANDLE"
73+
}
74+
},
75+
{
76+
"name": "Check password requirement",
77+
"status": 400,
78+
"return": 5003,
79+
"payload": {
80+
"username": "another_user"
81+
}
82+
},
83+
{
84+
"name": "Check privilege validation",
85+
"status": 400,
86+
"return": 5006,
87+
"payload": {
88+
"username": "another_user",
89+
"password": "changeme",
90+
"priv": ["INVALID"]
91+
}
92+
},
93+
{
94+
"name": "Check user expiration date validation",
95+
"status": 400,
96+
"return": 5040,
97+
"payload": {
98+
"username": "another_user",
99+
"password": "changeme",
100+
"expires": "INVALID"
101+
}
102+
},
103+
20104
]
21105
put_tests = [
22106
{
@@ -32,12 +116,48 @@ class APIUnitTestUser(unit_test_framework.APIUnitTest):
32116
},
33117
"resp_time": 2 # Allow a couple seconds for user database to be updated
34118
},
119+
{
120+
"name": "Check privilege validation",
121+
"status": 400,
122+
"return": 5006,
123+
"payload": {
124+
"username": "new_user",
125+
"password": "changeme",
126+
"priv": ["INVALID"]
127+
}
128+
},
129+
{
130+
"name": "Check user expiration date validation",
131+
"status": 400,
132+
"return": 5040,
133+
"payload": {
134+
"username": "new_user",
135+
"password": "changeme",
136+
"expires": "INVALID"
137+
}
138+
},
35139

36140
]
37141
delete_tests = [
38142
{
39143
"name": "Delete local user",
40144
"payload": {"username": "new_user"}
145+
},
146+
{
147+
"name": "Delete disabled user",
148+
"payload": {"username": "disabled_user"}
149+
},
150+
{
151+
"name": "Check deletion of non-existing user",
152+
"status": 400,
153+
"return": 5001,
154+
"payload": {"username": "INVALID"}
155+
},
156+
{
157+
"name": "Check deletion of system users",
158+
"status": 400,
159+
"return": 5005,
160+
"payload": {"username": "admin"}
41161
}
42162
]
43163

tests/test_api_v1_user_privilege.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,29 @@ class APIUnitTestUserPrivilege(unit_test_framework.APIUnitTest):
88
"name": "Grant user privileges",
99
"payload": {
1010
"username": "admin",
11-
"priv": ["page-all", "page-system-usermanager"]
11+
"priv": ["page-all", "page-system-api"]
12+
}
13+
},
14+
{
15+
"name": "Check username requirement",
16+
"status": 400,
17+
"return": 5000,
18+
},
19+
{
20+
"name": "Check non-existing username",
21+
"status": 400,
22+
"return": 5001,
23+
"payload": {
24+
"username": "INVALID"
25+
}
26+
},
27+
{
28+
"name": "Check non-existing privileges",
29+
"status": 400,
30+
"return": 5006,
31+
"payload": {
32+
"username": "admin",
33+
"priv": ["INVALID"]
1234
}
1335
}
1436
]
@@ -17,7 +39,7 @@ class APIUnitTestUserPrivilege(unit_test_framework.APIUnitTest):
1739
"name": "Delete user privileges",
1840
"payload": {
1941
"username": "admin",
20-
"priv": ["page-system-usermanager"]
42+
"priv": ["page-system-api"]
2143
}
2244
}
2345
]

tests/unit_test_framework/__init__.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import pfsense_vshell
1516
import requests
1617
import argparse
1718
import json
@@ -122,14 +123,16 @@ def make_request(self, method, test_params):
122123
# Create authentication payload for local authentication
123124
if self.args.auth_mode == "local":
124125
test_params["payload"] = test_params.get("payload", {})
125-
test_params["payload"].update(self.auth_payload)
126+
test_params["payload"].update(test_params.get("auth_payload", self.auth_payload))
126127
headers = {}
127128
# Create authentication headers for token authentication
128129
elif self.args.auth_mode == "token":
129130
headers = {"Authorization": self.args.username + " " + self.args.password}
130131
# Create authentication headers for JWT authentication
131132
elif self.args.auth_mode == "jwt":
132-
headers = {"Authorization": "Bearer " + self.__request_jwt__()}
133+
headers = {
134+
"Authorization": "Bearer " + self.__request_jwt__(test_params.get("auth_payload", self.auth_payload))
135+
}
133136

134137
# Attempt to make the API call, if the request times out print timeout error
135138
try:
@@ -316,12 +319,12 @@ def __format_msg__(self, method, test_params, result, mode="failed"):
316319
)
317320
return msg
318321

319-
def __request_jwt__(self):
322+
def __request_jwt__(self, auth_payload):
320323
try:
321324
req = requests.request(
322325
"POST",
323326
url=self.args.scheme + "://" + self.args.host + ":" + str(self.args.port) + "/api/v1/access_token",
324-
data=json.dumps({"client-id": self.args.username, "client-token": self.args.password}),
327+
data=json.dumps(auth_payload),
325328
verify=False,
326329
timeout=self.args.timeout
327330
)

0 commit comments

Comments
 (0)