#!/usr/bin/env python3 '''Fetch the latest AMD 2FA code from gautam@exulthealthcare.com via Graph. Usage: amd-fetch-2fa-code # default: codes within last 15 min amd-fetch-2fa-code --since 60 # codes within last 60 seconds ''' import os, sys, re, urllib.request, urllib.parse, json, datetime as dt CREDS='/etc/amd/m365-creds' def env(): e={} for line in open(CREDS): if '=' in line: k,v=line.strip().split('=',1); e[k]=v return e def get_token(e): body=urllib.parse.urlencode({ 'client_id':e['M365_CLIENT_ID'],'client_secret':e['M365_CLIENT_SECRET'], 'scope':'https://graph.microsoft.com/.default','grant_type':'client_credentials' }).encode() req=urllib.request.Request(f'https://login.microsoftonline.com/{e["M365_TENANT_ID"]}/oauth2/v2.0/token', body, method='POST') with urllib.request.urlopen(req,timeout=10) as r: return json.loads(r.read())['access_token'] def find_code(e, tok, since_sec): params={'$orderby':'receivedDateTime desc','$top':'15','$select':'subject,from,bodyPreview,receivedDateTime'} qs=urllib.parse.urlencode(params) url=f'https://graph.microsoft.com/v1.0/users/{e["M365_MAILBOX"]}/messages?{qs}' req=urllib.request.Request(url, headers={'Authorization':'Bearer '+tok}) with urllib.request.urlopen(req,timeout=10) as r: data=json.loads(r.read()) cutoff=dt.datetime.now(dt.timezone.utc)-dt.timedelta(seconds=since_sec) for m in data.get('value',[]): sender=(m.get('from') or {}).get('emailAddress',{}).get('address','').lower() if 'advancedmd' not in sender: continue try: ts=dt.datetime.fromisoformat(m['receivedDateTime'].replace('Z','+00:00')) if ts