Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,10 @@
"flake8.importStrategy": "fromEnvironment",
"mypy-type-checker.importStrategy": "fromEnvironment",
"isort.importStrategy": "fromEnvironment",
"black-formatter.importStrategy": "fromEnvironment"
"black-formatter.importStrategy": "fromEnvironment",
"workbench.colorCustomizations": {
"activityBar.background": "#4D1C3B",
"titleBar.activeBackground": "#6B2752",
"titleBar.activeForeground": "#FDF8FB"
}
}
7 changes: 4 additions & 3 deletions descope/management/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,10 @@ class MgmtV1:
# jwt
update_jwt_path = "/v1/mgmt/jwt/update"
impersonate_path = "/v1/mgmt/impersonate"
mgmt_sign_in = "/v1/mgmt/auth/signin"
mgmt_sign_up = "/v1/mgmt/auth/signup"
mgmt_sign_up_or_in = "/v1/mgmt/auth/signup-in"
mgmt_sign_in_path = "/v1/mgmt/auth/signin"
mgmt_sign_up_path = "/v1/mgmt/auth/signup"
mgmt_sign_up_or_in_path = "/v1/mgmt/auth/signup-in"
anonymous_path = "/v1/mgmt/auth/anonymous"

# permission
permission_create_path = "/v1/mgmt/permission/create"
Expand Down
33 changes: 30 additions & 3 deletions descope/management/jwt.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def sign_in(
raise AuthException(400, ERROR_TYPE_INVALID_ARGUMENT, "JWT is required")

response = self._auth.do_post(
MgmtV1.mgmt_sign_in,
MgmtV1.mgmt_sign_in_path,
{
"loginId": login_id,
"stepup": login_options.stepup,
Expand Down Expand Up @@ -139,7 +139,7 @@ def sign_up(
"""

return self._sign_up_internal(
login_id, MgmtV1.mgmt_sign_up, user, signup_options
login_id, MgmtV1.mgmt_sign_up_path, user, signup_options
)

def sign_up_or_in(
Expand All @@ -157,7 +157,7 @@ def sign_up_or_in(
signup_options (MgmtSignUpOptions): signup options.
"""
return self._sign_up_internal(
login_id, MgmtV1.mgmt_sign_up_or_in, user, signup_options
login_id, MgmtV1.mgmt_sign_up_or_in_path, user, signup_options
)

def _sign_up_internal(
Expand Down Expand Up @@ -193,3 +193,30 @@ def _sign_up_internal(
resp = response.json()
jwt_response = self._auth.generate_jwt_response(resp, None, None)
return jwt_response

def anonymous(
self,
custom_claims: Optional[dict] = None,
tenant_id: Optional[str] = None,
) -> dict:
"""
Generate a JWT for an anonymous user.

Args:
customClaims dict: Custom claims to add to JWT
tenant_id (str): tenant id to set on DCT claim.
"""

response = self._auth.do_post(
MgmtV1.anonymous_path,
{
"customClaims": custom_claims,
"selectedTenant": tenant_id,
},
pswd=self._auth.management_key,
)
resp = response.json()
jwt_response = self._auth.generate_jwt_response(resp, None, None)
del jwt_response["firstSeen"]
del jwt_response["user"]
return jwt_response
35 changes: 32 additions & 3 deletions tests/management/test_jwt.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def test_sign_in(self):
network_resp.json.return_value = json.loads("""{"jwt": "response"}""")
mock_post.return_value = network_resp
client.mgmt.jwt.sign_in("loginId")
expected_uri = f"{common.DEFAULT_BASE_URL}{MgmtV1.mgmt_sign_in}"
expected_uri = f"{common.DEFAULT_BASE_URL}{MgmtV1.mgmt_sign_in_path}"
mock_post.assert_called_with(
expected_uri,
headers={
Expand Down Expand Up @@ -204,7 +204,7 @@ def test_sign_up(self):
network_resp.json.return_value = json.loads("""{"jwt": "response"}""")
mock_post.return_value = network_resp
client.mgmt.jwt.sign_up("loginId")
expected_uri = f"{common.DEFAULT_BASE_URL}{MgmtV1.mgmt_sign_up}"
expected_uri = f"{common.DEFAULT_BASE_URL}{MgmtV1.mgmt_sign_up_path}"
mock_post.assert_called_with(
expected_uri,
headers={
Expand Down Expand Up @@ -253,7 +253,7 @@ def test_sign_up_or_in(self):
network_resp.json.return_value = json.loads("""{"jwt": "response"}""")
mock_post.return_value = network_resp
client.mgmt.jwt.sign_up_or_in("loginId")
expected_uri = f"{common.DEFAULT_BASE_URL}{MgmtV1.mgmt_sign_up_or_in}"
expected_uri = f"{common.DEFAULT_BASE_URL}{MgmtV1.mgmt_sign_up_or_in_path}"
mock_post.assert_called_with(
expected_uri,
headers={
Expand Down Expand Up @@ -283,3 +283,32 @@ def test_sign_up_or_in(self):
params=None,
timeout=DEFAULT_TIMEOUT_SECONDS,
)

def test_anonymous(self):
client = DescopeClient(
self.dummy_project_id,
self.public_key_dict,
False,
self.dummy_management_key,
)

# Test success flow
with patch("requests.post") as mock_post:
network_resp = mock.Mock()
network_resp.ok = True
network_resp.json.return_value = json.loads("""{"jwt": "response"}""")
mock_post.return_value = network_resp
client.mgmt.jwt.anonymous({"k1": "v1"}, "id")
expected_uri = f"{common.DEFAULT_BASE_URL}{MgmtV1.anonymous_path}"
mock_post.assert_called_with(
expected_uri,
headers={
**common.default_headers,
"Authorization": f"Bearer {self.dummy_project_id}:{self.dummy_management_key}",
},
json={"customClaims": {"k1": "v1"}, "selectedTenant": "id"},
allow_redirects=False,
verify=True,
params=None,
timeout=DEFAULT_TIMEOUT_SECONDS,
)
Loading