Skip to content

Commit 55aa877

Browse files
Updating nexusidentity - Resolves installation issue caused by Graphs Python SDK package. (#9102)
* updating nexusidentity - Resolves installation issue caused by Graphs Python SDK package where a long path error occured. To fix this - SDK support was removed and replaced with httpclient * fixing a small security concern with shell * retrigger checks * retrigger checks
1 parent 3b3cd48 commit 55aa877

File tree

3 files changed

+103
-66
lines changed

3 files changed

+103
-66
lines changed

src/nexusidentity/HISTORY.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
Release History
44
===============
55

6+
1.0.0b6
7+
+++++++
8+
* Resolves installation issue caused by Graphs Python SDK package where a long path error occured. To fix this - SDK support was removed and replaced with httpclient.
9+
610
1.0.0b5
711
+++++++
812
* Adding support for older algorithm ssh keys

src/nexusidentity/azext_nexusidentity/custom.py

Lines changed: 98 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,10 @@ def generate_nexus_identity_keys(algorithm=None):
1818

1919
import os
2020
import subprocess
21-
import asyncio
2221
import sys
23-
24-
from azure.identity import AzureCliCredential
25-
from msgraph import GraphServiceClient
26-
from msgraph.generated.models.open_type_extension import OpenTypeExtension
27-
from msgraph.generated.models.extension import Extension
28-
from azure.core.exceptions import ClientAuthenticationError, HttpResponseError
29-
from msgraph.generated.models.o_data_errors.o_data_error import ODataError
22+
import requests
23+
import json
24+
import shutil
3025

3126
# Generate SSH key
3227
if sys.platform.startswith("win") or sys.platform.startswith("linux"):
@@ -84,66 +79,105 @@ def generate_nexus_identity_keys(algorithm=None):
8479
raise CLIError(f"Unexpected error reading public key: {e}") from e
8580

8681
try:
87-
credential = AzureCliCredential()
88-
scopes = ["https://graph.microsoft.com//.default"]
89-
graph_client = GraphServiceClient(credentials=credential, scopes=scopes)
90-
91-
except ClientAuthenticationError as e:
92-
logger.error("Authentication failed: %s", e)
93-
raise CLIError(f"Authentication failed: {e}") from e
82+
# Get access token using Azure CLI
83+
if sys.platform.startswith("win"):
84+
az_path = shutil.which("az")
85+
if not az_path:
86+
raise CLIError("Azure CLI (az) not found in system")
87+
token_result = subprocess.run(
88+
[
89+
az_path,
90+
"account",
91+
"get-access-token",
92+
"--resource",
93+
"https://graph.microsoft.com",
94+
"--output",
95+
"json",
96+
],
97+
capture_output=True,
98+
text=True,
99+
check=True,
100+
)
101+
else:
102+
token_result = subprocess.run(
103+
[
104+
"az",
105+
"account",
106+
"get-access-token",
107+
"--resource",
108+
"https://graph.microsoft.com",
109+
"--output",
110+
"json",
111+
],
112+
capture_output=True,
113+
text=True,
114+
check=True,
115+
)
116+
access_token = json.loads(token_result.stdout)["accessToken"]
94117
except Exception as e:
95-
logger.error("An unexpected error occurred: %s", e)
96-
raise CLIError(f"An unexpected error occurred: {e}") from e
97-
98-
async def me():
99-
extension_id = "com.nexusidentity.keys"
100-
101-
# Get user object
102-
user = await graph_client.me.get()
118+
print("Exception to fetch bearer token:", e)
119+
logger.error("Failed to obtain access token: %s", e)
120+
raise CLIError(f"Failed to obtain access token: {e}") from e
103121

104-
# Get extensions associated with the user
105-
extensions = await graph_client.me.extensions.get()
122+
headers = {
123+
"Authorization": f"Bearer {access_token}",
124+
"Content-Type": "application/json",
125+
}
106126

107-
extension_exists = any(
108-
extension.id == extension_id for extension in extensions.value
109-
)
127+
extension_id = "com.nexusidentity.keys"
128+
graph_base = "https://graph.microsoft.com/v1.0"
110129

111-
try:
112-
# Update or create extension
113-
if extension_exists:
114-
request_body = Extension(
115-
odata_type="microsoft.graph.openTypeExtension",
116-
additional_data={
117-
"extension_name": extension_id,
118-
"publicKey": public_key,
119-
},
120-
)
121-
await graph_client.me.extensions.by_extension_id(
122-
extension_id
123-
).patch(request_body)
124-
125-
print(
126-
f"Successfully updated public key to Microsoft Entra Id account {user.mail}"
127-
)
128-
else:
129-
request_body = OpenTypeExtension(
130-
odata_type="microsoft.graph.openTypeExtension",
131-
extension_name=extension_id,
132-
additional_data={"publicKey": public_key},
133-
)
134-
await graph_client.me.extensions.post(request_body)
135-
136-
print(
137-
f"Successfully uploaded public key to Microsoft Entra Id account {user.mail}"
138-
)
139-
except ODataError as e:
140-
logger.error("Error updating extension: %s", e)
141-
raise CLIError(f"Error updating extension: {e}") from e
142-
except HttpResponseError as e:
143-
logger.error("Failed to update or create extension: %s", e)
144-
raise CLIError(f"Failed to update or create extension: {e}") from e
145-
146-
asyncio.run(me())
130+
try:
131+
# Get user info
132+
user = requests.get(f"{graph_base}/me", headers=headers)
133+
user.raise_for_status()
134+
user = user.json()
135+
136+
# Get extensions
137+
ext_resp = requests.get(f"{graph_base}/me/extensions", headers=headers)
138+
ext_resp.raise_for_status()
139+
ext_resp = ext_resp.json().get("value", [])
140+
extension_exists = any(ext.get("id") == extension_id for ext in ext_resp)
141+
142+
if extension_exists:
143+
# Update extension
144+
patch_body = {
145+
"@odata.type": "microsoft.graph.openTypeExtension",
146+
"extensionName": extension_id,
147+
"publicKey": public_key,
148+
}
149+
requests.patch(
150+
f"{graph_base}/me/extensions/{extension_id}",
151+
headers=headers,
152+
data=json.dumps(patch_body),
153+
).raise_for_status()
154+
print(
155+
f"Successfully updated public key to Microsoft Entra Id account "
156+
f"{user.get('mail') or user.get('userPrincipalName')}"
157+
)
158+
else:
159+
# Create extension
160+
post_body = {
161+
"@odata.type": "microsoft.graph.openTypeExtension",
162+
"extensionName": extension_id,
163+
"publicKey": public_key,
164+
}
165+
requests.post(
166+
f"{graph_base}/me/extensions",
167+
headers=headers,
168+
data=json.dumps(post_body),
169+
).raise_for_status()
170+
print(
171+
f"Successfully uploaded public key to Microsoft Entra Id account "
172+
f"{user.get('mail') or user.get('userPrincipalName')}"
173+
)
174+
175+
except requests.HTTPError as e:
176+
logger.error("HTTP error: %s", e)
177+
raise CLIError(f"HTTP error: {e}") from e
178+
except Exception as e:
179+
logger.error("Unexpected error: %s", e)
180+
raise CLIError(f"Unexpected error: {e}") from e
147181
else:
148182
logger.warning(
149183
"This command is currently supported only on Windows and linux platforms"

src/nexusidentity/setup.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
# TODO: Confirm this is the right version number you want and it matches your
1818
# HISTORY.rst entry.
19-
VERSION = '1.0.0b5'
19+
VERSION = '1.0.0b6'
2020

2121
# The full list of classifiers is available at
2222
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
@@ -35,7 +35,6 @@
3535
# TODO: Add any additional SDK dependencies here
3636
DEPENDENCIES = [
3737
'azure-identity==1.17.1',
38-
'msgraph-sdk'
3938
]
4039

4140
with open('README.md', 'r', encoding='utf-8') as f:

0 commit comments

Comments
 (0)