diff --git a/src/nexusidentity/HISTORY.rst b/src/nexusidentity/HISTORY.rst index 5e9849244f5..2cf89b57cf7 100644 --- a/src/nexusidentity/HISTORY.rst +++ b/src/nexusidentity/HISTORY.rst @@ -3,6 +3,10 @@ Release History =============== +1.0.0b6 ++++++++ +* 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. + 1.0.0b5 +++++++ * Adding support for older algorithm ssh keys diff --git a/src/nexusidentity/azext_nexusidentity/custom.py b/src/nexusidentity/azext_nexusidentity/custom.py index 7b3c6578867..8c9c9b041f0 100644 --- a/src/nexusidentity/azext_nexusidentity/custom.py +++ b/src/nexusidentity/azext_nexusidentity/custom.py @@ -18,15 +18,10 @@ def generate_nexus_identity_keys(algorithm=None): import os import subprocess - import asyncio import sys - - from azure.identity import AzureCliCredential - from msgraph import GraphServiceClient - from msgraph.generated.models.open_type_extension import OpenTypeExtension - from msgraph.generated.models.extension import Extension - from azure.core.exceptions import ClientAuthenticationError, HttpResponseError - from msgraph.generated.models.o_data_errors.o_data_error import ODataError + import requests + import json + import shutil # Generate SSH key if sys.platform.startswith("win") or sys.platform.startswith("linux"): @@ -84,66 +79,105 @@ def generate_nexus_identity_keys(algorithm=None): raise CLIError(f"Unexpected error reading public key: {e}") from e try: - credential = AzureCliCredential() - scopes = ["https://graph.microsoft.com//.default"] - graph_client = GraphServiceClient(credentials=credential, scopes=scopes) - - except ClientAuthenticationError as e: - logger.error("Authentication failed: %s", e) - raise CLIError(f"Authentication failed: {e}") from e + # Get access token using Azure CLI + if sys.platform.startswith("win"): + az_path = shutil.which("az") + if not az_path: + raise CLIError("Azure CLI (az) not found in system") + token_result = subprocess.run( + [ + az_path, + "account", + "get-access-token", + "--resource", + "https://graph.microsoft.com", + "--output", + "json", + ], + capture_output=True, + text=True, + check=True, + ) + else: + token_result = subprocess.run( + [ + "az", + "account", + "get-access-token", + "--resource", + "https://graph.microsoft.com", + "--output", + "json", + ], + capture_output=True, + text=True, + check=True, + ) + access_token = json.loads(token_result.stdout)["accessToken"] except Exception as e: - logger.error("An unexpected error occurred: %s", e) - raise CLIError(f"An unexpected error occurred: {e}") from e - - async def me(): - extension_id = "com.nexusidentity.keys" - - # Get user object - user = await graph_client.me.get() + print("Exception to fetch bearer token:", e) + logger.error("Failed to obtain access token: %s", e) + raise CLIError(f"Failed to obtain access token: {e}") from e - # Get extensions associated with the user - extensions = await graph_client.me.extensions.get() + headers = { + "Authorization": f"Bearer {access_token}", + "Content-Type": "application/json", + } - extension_exists = any( - extension.id == extension_id for extension in extensions.value - ) + extension_id = "com.nexusidentity.keys" + graph_base = "https://graph.microsoft.com/v1.0" - try: - # Update or create extension - if extension_exists: - request_body = Extension( - odata_type="microsoft.graph.openTypeExtension", - additional_data={ - "extension_name": extension_id, - "publicKey": public_key, - }, - ) - await graph_client.me.extensions.by_extension_id( - extension_id - ).patch(request_body) - - print( - f"Successfully updated public key to Microsoft Entra Id account {user.mail}" - ) - else: - request_body = OpenTypeExtension( - odata_type="microsoft.graph.openTypeExtension", - extension_name=extension_id, - additional_data={"publicKey": public_key}, - ) - await graph_client.me.extensions.post(request_body) - - print( - f"Successfully uploaded public key to Microsoft Entra Id account {user.mail}" - ) - except ODataError as e: - logger.error("Error updating extension: %s", e) - raise CLIError(f"Error updating extension: {e}") from e - except HttpResponseError as e: - logger.error("Failed to update or create extension: %s", e) - raise CLIError(f"Failed to update or create extension: {e}") from e - - asyncio.run(me()) + try: + # Get user info + user = requests.get(f"{graph_base}/me", headers=headers) + user.raise_for_status() + user = user.json() + + # Get extensions + ext_resp = requests.get(f"{graph_base}/me/extensions", headers=headers) + ext_resp.raise_for_status() + ext_resp = ext_resp.json().get("value", []) + extension_exists = any(ext.get("id") == extension_id for ext in ext_resp) + + if extension_exists: + # Update extension + patch_body = { + "@odata.type": "microsoft.graph.openTypeExtension", + "extensionName": extension_id, + "publicKey": public_key, + } + requests.patch( + f"{graph_base}/me/extensions/{extension_id}", + headers=headers, + data=json.dumps(patch_body), + ).raise_for_status() + print( + f"Successfully updated public key to Microsoft Entra Id account " + f"{user.get('mail') or user.get('userPrincipalName')}" + ) + else: + # Create extension + post_body = { + "@odata.type": "microsoft.graph.openTypeExtension", + "extensionName": extension_id, + "publicKey": public_key, + } + requests.post( + f"{graph_base}/me/extensions", + headers=headers, + data=json.dumps(post_body), + ).raise_for_status() + print( + f"Successfully uploaded public key to Microsoft Entra Id account " + f"{user.get('mail') or user.get('userPrincipalName')}" + ) + + except requests.HTTPError as e: + logger.error("HTTP error: %s", e) + raise CLIError(f"HTTP error: {e}") from e + except Exception as e: + logger.error("Unexpected error: %s", e) + raise CLIError(f"Unexpected error: {e}") from e else: logger.warning( "This command is currently supported only on Windows and linux platforms" diff --git a/src/nexusidentity/setup.py b/src/nexusidentity/setup.py index 37149b4e712..22836f0f52c 100644 --- a/src/nexusidentity/setup.py +++ b/src/nexusidentity/setup.py @@ -16,7 +16,7 @@ # TODO: Confirm this is the right version number you want and it matches your # HISTORY.rst entry. -VERSION = '1.0.0b5' +VERSION = '1.0.0b6' # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers @@ -35,7 +35,6 @@ # TODO: Add any additional SDK dependencies here DEPENDENCIES = [ 'azure-identity==1.17.1', - 'msgraph-sdk' ] with open('README.md', 'r', encoding='utf-8') as f: