- credentials: sifrovani AES-GCM/HKDF odstraneno, tri hlavicky se berou
tak, jak jsou; bez hlavicek se pouziji hodnoty z prostredi
- zrusena promenna MS365_CREDENTIAL_ENCODING_SECRET a zavislost cryptography
- novy endpoint GET /users/{user_id}/calendar (objekt kalendare schranky,
id a name) pro read-only overeni pristupu pres e-mail schranky
- C# ukazka posila hodnoty primo, CredentialEncoder smazan
- README: sekce o hlavickach vcetne PowerShell ukazky, zaznam zmen
- .gitignore: bin/ a obj/, zaverzovane obj/ soubory ukazky odstraneny z gitu
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
7.5 KiB
Microsoft 365 Service
FastAPI služba pro server-to-server komunikaci s Microsoft 365 přes Microsoft Graph.
Konfigurace
V Microsoft Entra ID vytvořte app registration, přidělte požadovaná aplikační oprávnění pro Microsoft Graph a nastavte tyto environment proměnné:
MS365_TENANT_ID=00000000-0000-0000-0000-000000000000
MS365_CLIENT_ID=00000000-0000-0000-0000-000000000000
MS365_CLIENT_SECRET=secret-value
MS365_GRAPH_BASE_URL=https://graph.microsoft.com/v1.0
MS365_GRAPH_SCOPE=https://graph.microsoft.com/.default
MS365_REQUEST_TIMEOUT_SECONDS=30
Služba používá OAuth2 client credentials flow, takže oprávnění pro Microsoft Graph musí být aplikační oprávnění schválená administrátorem.
Credentials v request hlavičkách
Credentials se posílají v každém requestu v hlavičkách jako obyčejné hodnoty:
X-MS365-Tenant-Id: <tenant id klienta>
X-MS365-Client-Id: <client id aplikace CSBOT>
X-MS365-Client-Secret: <client secret VALUE aplikace CSBOT, ne secret id>
Všechny tři hlavičky musí být pohromadě, jinak služba vrátí 400. Když se nepošle
žádná, použijí se MS365_TENANT_ID, MS365_CLIENT_ID a MS365_CLIENT_SECRET
z prostředí služby.
Příklad v PowerShellu:
$Headers = @{
"X-MS365-Tenant-Id" = $TenantId
"X-MS365-Client-Id" = $ClientId
"X-MS365-Client-Secret" = $ClientSecret
}
Invoke-RestMethod -Method Get -Headers $Headers `
-Uri "https://services.csbot.cz/apps/microsoft-365-service/users/$UserMailbox/calendar"
Multitenant napojení klientů (CSBOT MS365 Connector)
Služba je stavěná pro jednu multitenant Entra aplikaci CSBOT, přes kterou se připojují Microsoft 365 tenanty jednotlivých klientů. Podrobné zadání je v Notion stránce "MS365 práva konektoru".
MS365_CLIENT_IDaMS365_CLIENT_SECRETpatří aplikaci CSBOT a jsou pro všechny klienty stejné.MS365_TENANT_IDje tenant konkrétního klienta. Token se získává protihttps://login.microsoftonline.com/{tenant klienta}/oauth2/v2.0/token.- Při volání za různé klienty se tenant id posílá v hlavičce
X-MS365-Tenant-Id(viz "Credentials v request hlavičkách"), client id a secret zůstávají stejné. - Klient nevytváří vlastní App Registration ani nepředává secret. Jeho administrátor jen
schválí admin consent. URL pro consent vrací
GET /admin-consent/url?redirect_uri=...&state=...(bere tenant id a client id z hlaviček nebo z env). Callback po consentu (parametrytenantaadmin_consent=True) zpracovává backend CSBOT, ne tato služba. - Služba je bezstavová a neověřuje, zda mailbox, plan id nebo bucket id patří danému zákazníkovi. Tenant isolation (customer id -> tenant id, mailbox, plan id, bucket id) musí držet volající backend, hodnoty nesmí přicházet přímo od LLM.
Postup testu po consentu klienta: GET /status, GET /users/{mailbox}/calendar
(vrátí id a name kalendáře, nejlevnější ověření přístupu), GET /users/{mailbox}/calendar/view,
POST /users/{mailbox}/calendar/events + DELETE, GET /planner/plans/{plan_id}/tasks,
POST /planner/tasks + DELETE.
Implementované služby
- Users: výpis a načtení uživatelů.
- Mail: výpis zpráv a odesílání e-mailů včetně příloh.
- Calendar: načtení kalendáře schránky (id, name), výpis událostí, calendarView v zadaném rozsahu, volné termíny (getSchedule), načtení, vytvoření, úprava a smazání události včetně Teams online meetingů.
- Planner: výpis plánů skupiny, bucketů a tasků plánu, načtení, vytvoření, úprava
a smazání tasku. Úprava a smazání používají ETag (
If-Match). Když hlavička chybí, služba si aktuální ETag načte sama. - OneDrive: výpis souborů v rootu a upload malých souborů.
- Groups a Teams: výpis skupin a výpis kanálů týmu.
- Admin consent: sestavení consent URL pro administrátora klientského tenantu.
API
GET /health
GET /version
GET /status
GET /users?top=25&search=jane
GET /users/{user_id}
GET /users/{user_id}/mail/messages?folder=Inbox&top=25
POST /users/{user_id}/mail/send
GET /admin-consent/url?redirect_uri=...&state=...
GET /users/{user_id}/calendar
GET /users/{user_id}/calendar/events?top=25
POST /users/{user_id}/calendar/events
GET /users/{user_id}/calendar/view?start=...&end=...&top=25&time_zone=Europe/Prague
POST /users/{user_id}/calendar/schedule
GET /users/{user_id}/calendar/events/{event_id}
PATCH /users/{user_id}/calendar/events/{event_id}
DELETE /users/{user_id}/calendar/events/{event_id}
GET /users/{user_id}/drive/root/children?top=25
PUT /users/{user_id}/drive/root/{path}
GET /groups?top=25
GET /groups/{group_id}/planner/plans
GET /teams/{team_id}/channels
GET /planner/plans/{plan_id}/buckets
GET /planner/plans/{plan_id}/tasks
POST /planner/tasks
GET /planner/tasks/{task_id}
PATCH /planner/tasks/{task_id} (volitelně hlavička If-Match)
DELETE /planner/tasks/{task_id} (volitelně hlavička If-Match)
Parametry start a end u calendarView jsou ISO 8601 s offsetem, například
2026-09-08T08:00:00+02:00. Datumy u Planneru (due_date_time, start_date_time)
jsou ISO 8601 s offsetem, například 2026-09-10T16:00:00Z. Řešitelé se předávají
jako Graph user id v assign_user_ids, odebírají v unassign_user_ids.
user_id může být Microsoft Graph user id nebo user principal name, například jane@example.com.
Požadovaná Graph oprávnění
Přidělte pouze oprávnění, která dané nasazení skutečně používá:
- Users:
User.Read.All - Čtení mailů:
Mail.Read - Odesílání mailů:
Mail.Send - Čtení a zápis do kalendáře, calendarView, getSchedule:
Calendars.ReadWrite - Planner:
Tasks.ReadWrite.All(zahrnuje i čtení,Tasks.Read.Allnetřeba) - Čtení a zápis do OneDrive:
Files.ReadWrite.All - Výpis skupin a Teams kanálů:
Group.Read.All,Team.ReadBasic.All,Channel.ReadBasic.All
Pro konektor CSBOT (Calendar + Planner) je minimum Calendars.ReadWrite a Tasks.ReadWrite.All,
obě jako Application permissions. Calendars.ReadWrite platí na všechny mailboxy tenantu,
omezení na konkrétní mailbox se řeší na straně klienta v Exchange Online
(application access policy), ne v této službě.
Ukázky pro klienty
examples/csharp/ListUsersTop10: konzolová aplikace .NET 8, voláGET /users?top=10s hlavičkamiX-MS365-*. Popis vexamples/csharp/README.md.
Lokální spuštění
pip install -r requirements.txt
uvicorn app.main:app --reload
Vygenerované OpenAPI UI otevřete na http://localhost:8000/docs.
job queue test Thu May 28 02:12:07 PM CEST 2026
job queue test Thu May 28 02:12:28 PM CEST 2026
websocket logs test Fri May 29 11:03:58 AM CEST 2026
Záznam změn
-
2026-09-22: šifrování hlaviček
X-MS365-*odstraněno, hodnoty se posílají tak, jak jsou. Zrušena proměnnáMS365_CREDENTIAL_ENCODING_SECRETa závislostcryptography. -
2026-09-22:
GET /users/{user_id}/calendar(objekt kalendáře schránky, id a name) pro read-only ověření přístupu ke kalendáři klienta přes e-mail schránky. -
2026-09-09: verze 1.1.0. Podle Notion zadání "MS365 práva konektoru" doplněn Calendar (calendarView, getSchedule, get/patch/delete události), Planner (plány, buckety, tasky, create/patch/delete s ETag) a
GET /admin-consent/url. Kód ověřen jen importem aplikace a serializací schémat, proti reálnému tenantu netestováno (chybí DEV App Registration). -
2026-09-09: přidána C# ukázka
examples/csharp/ListUsersTop10(top 10 z/users).