Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,7 @@ create_resp = descope_client.mgmt.access_key.create(
],
description="this is my access key",
permitted_ips=['10.0.0.1', '192.168.1.0/24'],
custom_attributes={'attrName': 'attrValue'},
)
key = create_resp["key"]
cleartext = create_resp["cleartext"] # make sure to save the returned cleartext securely. It will not be returned again.
Expand All @@ -826,7 +827,8 @@ access_key_resp = descope_client.mgmt.access_key.load("key-id")
access_key = access_key_resp["key"]

# Search all access keys, optionally according to a tenant filter
keys_resp = descope_client.mgmt.access_key.search_all_access_keys(tenant_ids=["my-tenant-id"])
keys_resp = descope_client.mgmt.access_key.search_all_access_keys(tenant_ids=["my-tenant-id"], bound_user_id='buid',
creating_user='cu', custom_attributes={'attrName': 'attrValue'})
keys = keys_resp["keys"]
for key in keys:
# Do something
Expand All @@ -835,6 +837,9 @@ keys = keys_resp["keys"]
descope_client.mgmt.access_key.update(
id="key-id",
name="new name",
custom_claims={"k1":"v1"},
permitted_ips=['10.0.0.1', '192.168.1.0/24'],
custom_attributes={'attrName': 'attrValue'},
)

# Access keys can be deactivated to prevent usage. This can be undone using "activate".
Expand Down
38 changes: 36 additions & 2 deletions descope/management/access_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def create(
custom_claims: Optional[dict] = None,
description: Optional[str] = None,
permitted_ips: Optional[List[str]] = None,
custom_attributes: Optional[dict] = None,
) -> dict:
"""
Create a new access key.
Expand All @@ -35,6 +36,7 @@ def create(
custom_claims (dict): Optional, map of claims and their values that will be present in the JWT.
description (str): an optional text the access key can hold.
permitted_ips: (List[str]): An optional list of IP addresses or CIDR ranges that are allowed to use the access key.
custom_attributes (dict): Optional, map of custom attributes and their values that will be associated with the access key.

Return value (dict):
Return dict in the format
Expand Down Expand Up @@ -62,6 +64,7 @@ def create(
custom_claims,
description,
permitted_ips,
custom_attributes,
),
)
return response.json()
Expand Down Expand Up @@ -93,12 +96,18 @@ def load(
def search_all_access_keys(
self,
tenant_ids: Optional[List[str]] = None,
bound_user_id: Optional[str] = None,
creating_user: Optional[str] = None,
custom_attributes: Optional[dict] = None,
) -> dict:
"""
Search all access keys.

Args:
tenant_ids (List[str]): Optional list of tenant IDs to filter by
bound_user_id (str): Optional user ID of bounded user to filter by
creating_user (str): Optional user name of the creator to filter by
custom_attributes (dict): Optional dictionary of custom attributes to filter by

Return value (dict):
Return dict in the format
Expand All @@ -112,7 +121,12 @@ def search_all_access_keys(

response = self._http.post(
MgmtV1.access_keys_search_path,
body={"tenantIds": tenant_ids},
body={
"tenantIds": tenant_ids,
"boundUserId": bound_user_id,
"creatingUser": creating_user,
"customAttributes": custom_attributes,
},
)
return response.json()

Expand All @@ -121,6 +135,9 @@ def update(
id: str,
name: str,
description: Optional[str] = None,
custom_claims: Optional[dict] = None,
permitted_ips: Optional[List[str]] = None,
custom_attributes: Optional[dict] = None,
):
"""
Update an existing access key with the given various fields. IMPORTANT: id and name are mandatory fields.
Expand All @@ -129,13 +146,28 @@ def update(
id (str): The id of the access key to update.
name (str): The updated access key name.
description (str): The description of the access key to update. If not provided, it will not be overriden.
custom_claims (dict): Optional dictionary of custom claims to update. If not provided, it will not be overridden.
permitted_ips (List[str]): Optional list of permitted IPs to update. If not provided, it will not be overridden.
custom_attributes (dict): Optional dictionary of custom attributes to update. If not provided, it will not be overridden.

Raise:
AuthException: raised if update operation fails
"""
body: dict[str, str | List[str] | dict] = {
"id": id,
"name": name,
}
if description is not None:
body["description"] = description
if custom_claims is not None:
body["customClaims"] = custom_claims
if permitted_ips is not None:
body["permittedIps"] = permitted_ips
if custom_attributes is not None:
body["customAttributes"] = custom_attributes
self._http.post(
MgmtV1.access_key_update_path,
body={"id": id, "name": name, "description": description},
body=body,
)

def deactivate(
Expand Down Expand Up @@ -204,6 +236,7 @@ def _compose_create_body(
custom_claims: Optional[dict] = None,
description: Optional[str] = None,
permitted_ips: Optional[List[str]] = None,
custom_attributes: Optional[dict] = None,
) -> dict:
return {
"name": name,
Expand All @@ -214,4 +247,5 @@ def _compose_create_body(
"customClaims": custom_claims,
"description": description,
"permittedIps": permitted_ips,
"customAttributes": custom_attributes,
}
21 changes: 18 additions & 3 deletions tests/management/test_access_key.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ def test_create(self):
custom_claims={"k1": "v1"},
description="this is my access key",
permitted_ips=["10.0.0.1", "192.168.1.0/24"],
custom_attributes={"attr1": "value1"},
)
access_key = resp["key"]
self.assertEqual(access_key["id"], "ak1")
Expand All @@ -83,6 +84,7 @@ def test_create(self):
"customClaims": {"k1": "v1"},
"description": "this is my access key",
"permittedIps": ["10.0.0.1", "192.168.1.0/24"],
"customAttributes": {"attr1": "value1"},
},
allow_redirects=False,
verify=True,
Expand Down Expand Up @@ -153,7 +155,9 @@ def test_search_all_users(self):
"""{"keys": [{"id": "ak1"}, {"id": "ak2"}]}"""
)
mock_post.return_value = network_resp
resp = client.mgmt.access_key.search_all_access_keys(["t1, t2"])
resp = client.mgmt.access_key.search_all_access_keys(
["t1, t2"], "bound-user-id", "creator-user", {"attr1": "value1"}
)
keys = resp["keys"]
self.assertEqual(len(keys), 2)
self.assertEqual(keys[0]["id"], "ak1")
Expand All @@ -168,6 +172,9 @@ def test_search_all_users(self):
params=None,
json={
"tenantIds": ["t1, t2"],
"boundUserId": "bound-user-id",
"creatingUser": "creator-user",
"customAttributes": {"attr1": "value1"},
},
allow_redirects=False,
verify=True,
Expand Down Expand Up @@ -197,7 +204,12 @@ def test_update(self):
mock_post.return_value.ok = True
self.assertIsNone(
client.mgmt.access_key.update(
"key-id", name="new-name", description=None
"key-id",
name="new-name",
description="desc",
custom_claims={"k1": "v1"},
permitted_ips=["192.168.1.1"],
custom_attributes={"attr1": "value1"},
)
)
mock_post.assert_called_with(
Expand All @@ -211,7 +223,10 @@ def test_update(self):
json={
"id": "key-id",
"name": "new-name",
"description": None,
"description": "desc",
"customClaims": {"k1": "v1"},
"permittedIps": ["192.168.1.1"],
"customAttributes": {"attr1": "value1"},
},
allow_redirects=False,
verify=True,
Expand Down
Loading