Session Management
The Multi-Cloud Manager maintains server-side sessions that store user authentication state and connected cloud provider accounts. These endpoints allow clients to check authentication status, retrieve connected accounts, and manage sessions.
Get Current User
Response
When authenticated:
Always true when user is authenticated
User’s display name from the authentication provider
{
"logged_in": true,
"name": "John Doe"
}
When not authenticated:
Implementation Details
This endpoint checks for the presence of a user object in the session. The user object is set during OAuth callbacks for Azure and GCP authentication.
Code reference: backend/azure_modules/utils.py:46-50
def api_user():
user = get_user()
if not user:
return jsonify({"logged_in": False}), 200
return jsonify({"logged_in": True, "name": user.get("name")}), 200
Get Connected Accounts
Response
Returns an array of account objects, one for each connected cloud provider.
Array of connected cloud provider account objects
Azure Account Object:
Azure Active Directory tenant ID
User’s display name from Azure AD
Array of subscription IDs accessible by the user
GCP Account Object:
User’s Google email address
User’s display name from Google profile
Refresh token for obtaining new access tokens
AWS Account Object:
Display name in format: "AWS Account ({account_id})"
IAM role ARN for cross-account access
External ID used in role assumption
Example response:
[
{
"provider": "azure",
"tenantId": "12345678-1234-1234-1234-123456789012",
"displayName": "John Doe",
"subscriptions": [
"abcd1234-5678-90ab-cdef-1234567890ab",
"efgh5678-90ab-cdef-1234-567890abcdef"
]
},
{
"provider": "gcp",
"email": "[email protected]",
"displayName": "John Doe",
"access_token": "ya29.a0AfH6SMBx...",
"refresh_token": "1//0gHZx..."
},
{
"provider": "aws",
"displayName": "AWS Account (987654321098)",
"roleArn": "arn:aws:iam::987654321098:role/MultiCloudManagerRole",
"externalId": "multi-cloud-manager-app-v1-secret",
"accountId": "987654321098"
}
]
When no accounts connected:
Implementation Details
Code reference: backend/azure_modules/utils.py:42-44
def api_accounts():
accounts = session.get("accounts", [])
return jsonify(accounts), 200
Get Azure Subscriptions
Response
Array of Azure subscription objects with full details
Subscription Object:
Azure tenant ID that owns the subscription
Azure subscription ID (GUID)
Subscription display name from Azure
Example response:
{
"value": [
{
"provider": "azure",
"tenantId": "12345678-1234-1234-1234-123456789012",
"subscriptionId": "abcd1234-5678-90ab-cdef-1234567890ab",
"displayName": "Production Subscription"
},
{
"provider": "azure",
"tenantId": "12345678-1234-1234-1234-123456789012",
"subscriptionId": "efgh5678-90ab-cdef-1234-567890abcdef",
"displayName": "Development Subscription"
}
]
}
Error Responses
500 Internal Server Error
{
"error": "Error message details"
}
Returned when Azure SDK fails to list subscriptions (e.g., invalid credentials, expired tokens, permission issues).
Implementation Details
This endpoint:
- Iterates through all accounts in the session
- Filters for Azure accounts only (
provider == "azure")
- For each Azure account, creates a
SubscriptionClient using service principal credentials
- Lists all subscriptions using
client.subscriptions.list()
- Returns enriched subscription details with tenant ID and provider info
Code reference: backend/azure_modules/utils.py:52-69
def api_subscriptions():
accounts = session.get("accounts", [])
items = []
for acc in accounts:
if acc.get("provider") != "azure":
continue
try:
client = get_subscription_client(acc["tenantId"])
for s in client.subscriptions.list():
items.append({
"provider": "azure",
"tenantId": acc["tenantId"],
"subscriptionId": s.subscription_id,
"displayName": s.display_name
})
except Exception as e:
return jsonify({"error": str(e)}), 500
return jsonify({"value": items})
Logout
Response
200 OK
{
"message": "Wylogowano"
}
Implementation Details
Clears all session data including:
- User authentication info (
session["user"])
- Access tokens (
session["access_token"])
- Connected accounts (
session["accounts"])
- Any other session data
Code reference: backend/azure_modules/utils.py:38-40
def logout():
session.clear()
return jsonify({"message": "Wylogowano"}), 200
Note: After logout, the client should redirect the user to the login page or home page.
Session Storage
All session data is stored server-side using Flask sessions. The session is secured with a secret key configured in the application:
app.secret_key = "super-secret-key"
Security Note: In production, use a strong, randomly generated secret key and store it securely (environment variable or secrets manager).
Session Data Structure
session = {
"user": { # Set by Azure/GCP OAuth
"name": "John Doe",
"email": "[email protected]",
# ... other ID token claims
},
"access_token": "bearer_token_here",
"accounts": [
# Azure, GCP, and AWS account objects
]
}
CORS Configuration
The API is configured with CORS to allow requests from the frontend:
CORS(app, supports_credentials=True, origins=["http://localhost:3000"])
Important: Session cookies require supports_credentials=True and the client must send requests with credentials (e.g., credentials: 'include' in fetch API).
Authentication Flow
Initial Authentication
- User navigates to login page
- User clicks “Login with Azure” or “Login with Google”
- OAuth flow completes (see Azure Login or GCP Login pages)
- User object and access token stored in session
- User redirected to dashboard
Checking Authentication Status
// Frontend check
fetch('/api/user', { credentials: 'include' })
.then(res => res.json())
.then(data => {
if (data.logged_in) {
console.log('User:', data.name);
} else {
// Redirect to login
}
});
Loading Connected Accounts
// Get all connected accounts
fetch('/api/accounts', { credentials: 'include' })
.then(res => res.json())
.then(accounts => {
accounts.forEach(acc => {
console.log(`Connected: ${acc.provider} - ${acc.displayName}`);
});
});
Logging Out
// Logout
fetch('/api/logout', { credentials: 'include' })
.then(() => {
window.location.href = '/';
});
Code References
Session utilities: backend/azure_modules/utils.py:38-69
Get user helper:
def get_user():
return session.get("user")
Route registration: backend/azure_modules/routes.py:94-97
azure_bp_module.route("/api/user")(api_user)
azure_bp_module.route("/api/subscriptions")(api_subscriptions)
azure_bp_module.route("/api/accounts")(api_accounts)
azure_bp_module.route("/api/logout")(logout)