First commit
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
"""
|
||||
Azure Authentication Module
|
||||
|
||||
Handles authentication to Azure services for Key Vault management.
|
||||
"""
|
||||
|
||||
from azure.identity import InteractiveBrowserCredential
|
||||
from azure.mgmt.resource import SubscriptionClient
|
||||
from typing import Optional, List, Dict
|
||||
|
||||
|
||||
class AzureAuthenticator:
|
||||
"""Handles Azure authentication for Key Vault and resource management."""
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Initialize the Azure authenticator.
|
||||
"""
|
||||
self.tenant_id: Optional[str] = None
|
||||
self.subscription_id: Optional[str] = None
|
||||
self.credential: Optional[InteractiveBrowserCredential] = None
|
||||
self.subscriptions: List[Dict[str, str]] = []
|
||||
|
||||
def authenticate(self, credential: InteractiveBrowserCredential = None) -> bool:
|
||||
"""
|
||||
Authenticate to Azure. Can reuse credential from Graph authenticator.
|
||||
|
||||
Args:
|
||||
credential: Optional credential to reuse (from GraphAuthenticator)
|
||||
|
||||
Returns:
|
||||
bool: True if authentication succeeded, False otherwise
|
||||
|
||||
Raises:
|
||||
Exception: If authentication fails
|
||||
"""
|
||||
try:
|
||||
if credential:
|
||||
# Reuse credential from Graph authentication
|
||||
self.credential = credential
|
||||
else:
|
||||
# Create new interactive browser credential with "organizations" tenant
|
||||
# This allows the user to login with any organizational account
|
||||
# additionally_allowed_tenants="*" allows acquiring tokens for any tenant
|
||||
self.credential = InteractiveBrowserCredential(
|
||||
tenant_id="organizations",
|
||||
additionally_allowed_tenants=["*"]
|
||||
)
|
||||
|
||||
# List all subscriptions (this will use the cached token from Graph auth)
|
||||
sub_client = SubscriptionClient(self.credential)
|
||||
subscriptions_list = list(sub_client.subscriptions.list())
|
||||
|
||||
# Extract tenant ID from the first subscription
|
||||
if subscriptions_list:
|
||||
# Get tenant ID from subscription (format: /subscriptions/{sub-id})
|
||||
# The tenant info is in the subscription object
|
||||
first_sub = subscriptions_list[0]
|
||||
self.tenant_id = first_sub.tenant_id if hasattr(first_sub, 'tenant_id') else None
|
||||
if self.tenant_id:
|
||||
print(f"Detected Tenant ID: {self.tenant_id}")
|
||||
|
||||
if subscriptions_list:
|
||||
print(f"Successfully authenticated to Azure. Found {len(subscriptions_list)} subscription(s).")
|
||||
|
||||
# Store subscriptions for later selection
|
||||
self.subscriptions = [
|
||||
{
|
||||
'id': sub.subscription_id,
|
||||
'name': sub.display_name
|
||||
}
|
||||
for sub in subscriptions_list
|
||||
]
|
||||
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
raise Exception(f"Azure authentication failed: {str(e)}")
|
||||
|
||||
def get_credential(self) -> InteractiveBrowserCredential:
|
||||
"""
|
||||
Get the credential object.
|
||||
|
||||
Returns:
|
||||
InteractiveBrowserCredential: The credential object
|
||||
|
||||
Raises:
|
||||
Exception: If not authenticated
|
||||
"""
|
||||
if not self.credential:
|
||||
raise Exception("Not authenticated. Call authenticate() first.")
|
||||
return self.credential
|
||||
|
||||
def get_subscriptions(self) -> List[Dict[str, str]]:
|
||||
"""
|
||||
Get the list of available subscriptions.
|
||||
|
||||
Returns:
|
||||
List[Dict]: List of subscriptions with 'id' and 'name'
|
||||
"""
|
||||
return self.subscriptions
|
||||
|
||||
def set_subscription(self, subscription_id: str):
|
||||
"""
|
||||
Set the active subscription ID.
|
||||
|
||||
Args:
|
||||
subscription_id: The subscription ID to use
|
||||
"""
|
||||
self.subscription_id = subscription_id
|
||||
|
||||
def get_subscription_id(self) -> str:
|
||||
"""
|
||||
Get the subscription ID.
|
||||
|
||||
Returns:
|
||||
str: The subscription ID
|
||||
|
||||
Raises:
|
||||
Exception: If subscription not set
|
||||
"""
|
||||
if not self.subscription_id:
|
||||
raise Exception("Subscription not set. Call set_subscription() first.")
|
||||
return self.subscription_id
|
||||
|
||||
def get_tenant_id(self) -> str:
|
||||
"""
|
||||
Get the tenant ID.
|
||||
|
||||
Returns:
|
||||
str: The tenant ID
|
||||
|
||||
Raises:
|
||||
Exception: If not authenticated
|
||||
"""
|
||||
if not self.tenant_id:
|
||||
raise Exception("Tenant ID not available. Call authenticate() first.")
|
||||
return self.tenant_id
|
||||
|
||||
def is_authenticated(self) -> bool:
|
||||
"""
|
||||
Check if currently authenticated.
|
||||
|
||||
Returns:
|
||||
bool: True if authenticated, False otherwise
|
||||
"""
|
||||
return self.credential is not None
|
||||
Reference in New Issue
Block a user