Skip to content

Commit 079d9f4

Browse files
authored
feat: Added modified and created time parameters (#488)
1 parent 528411f commit 079d9f4

File tree

3 files changed

+122
-1
lines changed

3 files changed

+122
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ descope_client.mgmt.user.logout_user("<login-id>")
680680
descope_client.mgmt.user.logout_user_by_user_id("<user-id>")
681681

682682
# Search all users, optionally according to tenant and/or role filter
683-
# results can be paginated using the limit and page parameters
683+
# results can be paginated using the limit and page parameters, as well as by time with the from_created_time, to_created_time, from_modified_time, and to_modified_time
684684
users_resp = descope_client.mgmt.user.search_all(tenant_ids=["my-tenant-id"])
685685
users = users_resp["users"]
686686
for user in users:

descope/management/user.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,10 @@ def search_all(
595595
sort: Optional[List[Sort]] = None,
596596
text: Optional[str] = None,
597597
login_ids: Optional[List[str]] = None,
598+
from_created_time: Optional[int] = None,
599+
to_created_time: Optional[int] = None,
600+
from_modified_time: Optional[int] = None,
601+
to_modified_time: Optional[int] = None,
598602
) -> dict:
599603
"""
600604
Search all users.
@@ -614,6 +618,10 @@ def search_all(
614618
text (str): Optional string, allows free text search among all user's attributes.
615619
login_ids (List[str]): Optional list of login ids
616620
sort (List[Sort]): Optional List[dict], allows to sort by fields.
621+
from_created_time (int): Optional int, only include users who were created on or after this time (in Unix epoch milliseconds)
622+
to_created_time (int): Optional int, only include users who were created on or before this time (in Unix epoch milliseconds)
623+
from_modified_time (int): Optional int, only include users whose last modification/update occurred on or after this time (in Unix epoch milliseconds)
624+
to_modified_time (int): Optional int, only include users whose last modification/update occurred on or before this time (in Unix epoch milliseconds)
617625
618626
Return value (dict):
619627
Return dict in the format
@@ -667,6 +675,15 @@ def search_all(
667675
if sort is not None:
668676
body["sort"] = sort_to_dict(sort)
669677

678+
if from_created_time is not None:
679+
body["fromCreatedTime"] = from_created_time
680+
if to_created_time is not None:
681+
body["toCreatedTime"] = to_created_time
682+
if from_modified_time is not None:
683+
body["fromModifiedTime"] = from_modified_time
684+
if to_modified_time is not None:
685+
body["toModifiedTime"] = to_modified_time
686+
670687
response = self._auth.do_post(
671688
MgmtV1.users_search_path,
672689
body=body,
@@ -688,6 +705,10 @@ def search_all_test_users(
688705
sort: Optional[List[Sort]] = None,
689706
text: Optional[str] = None,
690707
login_ids: Optional[List[str]] = None,
708+
from_created_time: Optional[int] = None,
709+
to_created_time: Optional[int] = None,
710+
from_modified_time: Optional[int] = None,
711+
to_modified_time: Optional[int] = None,
691712
) -> dict:
692713
"""
693714
Search all test users.
@@ -705,6 +726,10 @@ def search_all_test_users(
705726
text (str): Optional string, allows free text search among all user's attributes.
706727
login_ids (List[str]): Optional list of login ids
707728
sort (List[Sort]): Optional List[dict], allows to sort by fields.
729+
from_created_time (int): Optional int, only include users who were created on or after this time (in Unix epoch milliseconds)
730+
to_created_time (int): Optional int, only include users who were created on or before this time (in Unix epoch milliseconds)
731+
from_modified_time (int): Optional int, only include users whose last modification/update occurred on or after this time (in Unix epoch milliseconds)
732+
to_modified_time (int): Optional int, only include users whose last modification/update occurred on or before this time (in Unix epoch milliseconds)
708733
709734
Return value (dict):
710735
Return dict in the format
@@ -758,6 +783,15 @@ def search_all_test_users(
758783
if sort is not None:
759784
body["sort"] = sort_to_dict(sort)
760785

786+
if from_created_time is not None:
787+
body["fromCreatedTime"] = from_created_time
788+
if to_created_time is not None:
789+
body["toCreatedTime"] = to_created_time
790+
if from_modified_time is not None:
791+
body["fromModifiedTime"] = from_modified_time
792+
if to_modified_time is not None:
793+
body["toModifiedTime"] = to_modified_time
794+
761795
response = self._auth.do_post(
762796
MgmtV1.test_users_search_path,
763797
body=body,

tests/management/test_user.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,51 @@ def test_search_all(self):
965965
verify=True,
966966
timeout=DEFAULT_TIMEOUT_SECONDS,
967967
)
968+
969+
# Test success flow with time parameters
970+
with patch("requests.post") as mock_post:
971+
network_resp = mock.Mock()
972+
network_resp.ok = True
973+
network_resp.json.return_value = json.loads(
974+
"""{"users": [{"id": "u1"}, {"id": "u2"}]}"""
975+
)
976+
mock_post.return_value = network_resp
977+
resp = self.client.mgmt.user.search_all(
978+
from_created_time=100,
979+
to_created_time=200,
980+
from_modified_time=300,
981+
to_modified_time=400,
982+
limit=10,
983+
page=0,
984+
)
985+
users = resp["users"]
986+
self.assertEqual(len(users), 2)
987+
self.assertEqual(users[0]["id"], "u1")
988+
self.assertEqual(users[1]["id"], "u2")
989+
# Verify the request body includes our time parameters
990+
mock_post.assert_called_with(
991+
f"{common.DEFAULT_BASE_URL}{MgmtV1.users_search_path}",
992+
headers={
993+
**common.default_headers,
994+
"Authorization": f"Bearer {self.dummy_project_id}:{self.dummy_management_key}",
995+
},
996+
params=None,
997+
json={
998+
"tenantIds": [],
999+
"roleNames": [],
1000+
"limit": 10,
1001+
"page": 0,
1002+
"testUsersOnly": False,
1003+
"withTestUser": False,
1004+
"fromCreatedTime": 100,
1005+
"toCreatedTime": 200,
1006+
"fromModifiedTime": 300,
1007+
"toModifiedTime": 400,
1008+
},
1009+
allow_redirects=False,
1010+
verify=True,
1011+
timeout=DEFAULT_TIMEOUT_SECONDS,
1012+
)
9681013

9691014
def test_search_all_test_users(self):
9701015
# Test failed flows
@@ -1127,6 +1172,48 @@ def test_search_all_test_users(self):
11271172
timeout=DEFAULT_TIMEOUT_SECONDS,
11281173
)
11291174

1175+
# Test success flow with time parameters
1176+
with patch("requests.post") as mock_post:
1177+
network_resp = mock.Mock()
1178+
network_resp.ok = True
1179+
network_resp.json.return_value = json.loads("""{"users": [{"id": "u1"}]}""")
1180+
mock_post.return_value = network_resp
1181+
resp = self.client.mgmt.user.search_all_test_users(
1182+
from_created_time=100,
1183+
to_created_time=200,
1184+
from_modified_time=300,
1185+
to_modified_time=400,
1186+
limit=10,
1187+
page=0,
1188+
)
1189+
users = resp["users"]
1190+
self.assertEqual(len(users), 1)
1191+
self.assertEqual(users[0]["id"], "u1")
1192+
# Verify the request body includes our time parameters
1193+
mock_post.assert_called_with(
1194+
f"{common.DEFAULT_BASE_URL}{MgmtV1.test_users_search_path}",
1195+
headers={
1196+
**common.default_headers,
1197+
"Authorization": f"Bearer {self.dummy_project_id}:{self.dummy_management_key}",
1198+
},
1199+
params=None,
1200+
json={
1201+
"tenantIds": [],
1202+
"roleNames": [],
1203+
"limit": 10,
1204+
"page": 0,
1205+
"testUsersOnly": True,
1206+
"withTestUser": True,
1207+
"fromCreatedTime": 100,
1208+
"toCreatedTime": 200,
1209+
"fromModifiedTime": 300,
1210+
"toModifiedTime": 400,
1211+
},
1212+
allow_redirects=False,
1213+
verify=True,
1214+
timeout=DEFAULT_TIMEOUT_SECONDS,
1215+
)
1216+
11301217
def test_get_provider_token(self):
11311218
# Test failed flows
11321219
with patch("requests.get") as mock_post:

0 commit comments

Comments
 (0)