import json
import logging
from datetime import datetime
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def write_to_json(app_registrations, filename='app_registrations.json'):
"""
Write app registration data to a JSON file.
:param app_registrations: List of app registration data
:param filename: Name of the JSON file to write to
"""
try:
with open(filename, 'w') as f:
json.dump(app_registrations, f, indent=4)
logging.info(f"App registration data successfully written to {filename}")
except Exception as e:
logging.error(f"Failed to write app registration data to {filename}: {e}")
def generate_html(app_registrations):
"""
Generate an HTML representation of the app registration data.
:param app_registrations: List of app registration data
:return: HTML string
"""
current_time = datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')
html = f"""
App Registrations
Azure App Registration Expiry Notification
This is an automated notification regarding expiring Azure App Registrations that you own or manage.
Why am I receiving this?
You are receiving this email because you are listed as an owner of one or more Azure App Registrations that are approaching their expiration date or have already expired.
Required Actions:
- Review the list of app registrations below
- For any expiring or expired registrations:
- Verify if the app registration is still needed
- If needed, renew the credentials before they expire
- If not needed, consider removing the app registration
Color Coding:
- Green: More than 30 days until expiry
- Yellow: Between 8-30 days until expiry
- Orange: 7 days or less until expiry
- Red: Expired
If you need assistance, please contact the IT Support team.
App Registrations
Exported on: {current_time}
| Display Name |
Expiry Date |
Days to Expiry |
Owners |
"""
for app in app_registrations:
password_credentials = app.get('passwordCredentials', [])
if not password_credentials:
continue
expiry_date = password_credentials[0].get('endDateTime')
if expiry_date:
# Clean up the date string
if expiry_date.endswith('ZZ'):
expiry_date = expiry_date[:-1]
elif expiry_date.endswith('Z'):
expiry_date = expiry_date[:-1]
# Truncate the fractional seconds part to 6 digits if present
if '.' in expiry_date:
expiry_date = expiry_date.split('.')[0] + '.' + expiry_date.split('.')[1][:6] + 'Z'
else:
expiry_date += '.000000Z'
try:
expiry_date = datetime.strptime(expiry_date, '%Y-%m-%dT%H:%M:%S.%fZ')
except ValueError as e:
logging.error(f"Error parsing expiry date for {app['displayName']}: {e}")
continue
days_to_expiry = (expiry_date - datetime.utcnow()).days
# Determine row color class
if days_to_expiry > 30:
color_class = "green"
elif 7 < days_to_expiry <= 30:
color_class = "yellow"
elif 1 <= days_to_expiry <= 7:
color_class = "orange"
else:
color_class = "red"
days_to_expiry = "EXPIRED"
# Get owner information
owners = app.get('owners', [])
owner_upns = [owner.get('userPrincipalName') for owner in owners if owner.get('userPrincipalName')]
owner_list = ', '.join(owner_upns) if owner_upns else 'No owners'
html += f"""
| {app['displayName']} |
{expiry_date.strftime('%Y-%m-%d')} |
{days_to_expiry} |
{owner_list} |
"""
html += """
"""
return html
def generate_expiry_text(app_name, days_to_expiry, expiry_date):
if days_to_expiry > 30:
color = "#28a745" # green
elif days_to_expiry > 7:
color = "#ffc107" # yellow
elif days_to_expiry > 0:
color = "#ff9800" # orange
else:
color = "#dc3545" # red
days_to_expiry = "EXPIRED"
return f"""
The app registration {app_name} is set to expire in
{days_to_expiry}
days on {expiry_date.strftime('%Y-%m-%d')}
"""
# Example usage
if __name__ == "__main__":
# Sample app registration data
app_registrations = [
{
"displayName": "App1",
"passwordCredentials": [{"endDateTime": "2024-12-31T23:59:59.9999999Z"}]
},
{
"displayName": "App2",
"passwordCredentials": [{"endDateTime": "2025-01-15T23:59:59.9999999Z"}]
}
]
# Write to JSON
write_to_json(app_registrations)
# Generate HTML
html_content = generate_html(app_registrations)
with open('app_registrations.html', 'w') as f:
f.write(html_content)
logging.info("HTML content successfully written to app_registrations.html")