Calendar a Planner endpointy, admin consent URL, C# ukazka (1.1.0)

Podle zadani "MS365 prava konektoru":
- Calendar: calendarView, getSchedule, get/patch/delete udalosti
- Planner: plany skupiny, buckety, tasky, create/patch/delete s ETag
- GET /admin-consent/url pro onboarding klientskeho tenantu
- examples/csharp/ListUsersTop10: ukazka volani GET /users?top=10
  vcetne sifrovani hlavicek X-MS365-*
- README: multitenant napojeni, endpointy, opravneni, zaznam zmen

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
JiriUhlir
2026-09-09 11:52:52 +02:00
co-authored by Claude Fable 5.1
parent 275bd6c467
commit fe3c3a736a
20 changed files with 877 additions and 9 deletions
+68 -2
View File
@@ -173,13 +173,41 @@ using var response = await http.SendAsync(request);
response.EnsureSuccessStatusCode();
```
## 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_ID` a `MS365_CLIENT_SECRET` patří aplikaci CSBOT a jsou pro všechny klienty stejné.
- `MS365_TENANT_ID` je tenant konkrétního klienta. Token se získává proti
`https://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 (parametry `tenant`
a `admin_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/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: výpis a vytváření událostí včetně Teams online meetingů.
- Calendar: 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
@@ -191,14 +219,32 @@ 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/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í
@@ -208,10 +254,22 @@ 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: `Calendars.ReadWrite`
- Čtení a zápis do kalendáře, calendarView, getSchedule: `Calendars.ReadWrite`
- Planner: `Tasks.ReadWrite.All` (zahrnuje i čtení, `Tasks.Read.All` netř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=10`
a obsahuje třídu `CredentialEncoder` pro šifrování hlaviček `X-MS365-*`.
Popis v `examples/csharp/README.md`.
## Lokální spuštění
```bash
@@ -223,3 +281,11 @@ 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-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`).