Skip to content

Commit 5430fe0

Browse files
MehakBindraMehak Bindra
andauthored
Add graph template and oauth config to python CLI (#336)
1. In `.vscode` remove configuration for starting app in test tools. 2. Add `aad.manifest.json` to add: ``` "resourceAppId": "Microsoft Graph", "resourceAccess": [ { "id": "User.Read", "type": "Scope" } ] ``` 3. Make bot SINGLE TENANT in `azurebot.bicep`. ``` msaAppId: botAadAppClientId msaAppType: 'SingleTenant' msaAppTenantId: tenantId ``` 4. Add `botServicesMicrosoftGraphConnection` resource in `azurebot.bicep` with correct scopes: `scopes: 'User.Read'` 5. With the graph template, user can do sign in with graph and view profile and mail info. <img width="911" height="457" alt="Screenshot 2025-09-08 162127" src="https://github.com/user-attachments/assets/073bc1b3-4298-4593-ae11-88509201f7da" /> <img width="816" height="518" alt="Screenshot 2025-09-08 162145" src="https://github.com/user-attachments/assets/d5503c35-e7fa-4264-bbeb-3dbf2974491e" /> CAVEAT: currently need to create Service Principal manually when app is registered. Should be automated soon. <img width="453" height="95" alt="Screenshot 2025-09-08 162906" src="https://github.com/user-attachments/assets/2a55fe5d-92f6-4382-ac7f-df049c4b953e" /> --------- Co-authored-by: Mehak Bindra <[email protected]>
1 parent 5a85fbc commit 5430fe0

File tree

15 files changed

+792
-2
lines changed

15 files changed

+792
-2
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
{
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "Launch Remote (Edge)",
6+
"type": "msedge",
7+
"request": "launch",
8+
"url": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}",
9+
"presentation": {
10+
"group": "remote",
11+
"order": 1
12+
},
13+
"internalConsoleOptions": "neverOpen"
14+
},
15+
{
16+
"name": "Launch Remote (Chrome)",
17+
"type": "chrome",
18+
"request": "launch",
19+
"url": "https://teams.microsoft.com/l/app/${{TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}",
20+
"presentation": {
21+
"group": "remote",
22+
"order": 2
23+
},
24+
"internalConsoleOptions": "neverOpen"
25+
},
26+
{
27+
"name": "Launch App (Edge)",
28+
"type": "msedge",
29+
"request": "launch",
30+
"url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}",
31+
"presentation": {
32+
"group": "all",
33+
"hidden": true
34+
},
35+
"internalConsoleOptions": "neverOpen"
36+
},
37+
{
38+
"name": "Launch App (Chrome)",
39+
"type": "chrome",
40+
"request": "launch",
41+
"url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}",
42+
"presentation": {
43+
"group": "all",
44+
"hidden": true
45+
},
46+
"internalConsoleOptions": "neverOpen"
47+
},
48+
{
49+
"name": "Start",
50+
"type": "debugpy",
51+
"request": "launch",
52+
"program": "${workspaceFolder}/src/main.py",
53+
"console": "integratedTerminal"
54+
}
55+
],
56+
"compounds": [
57+
{
58+
"name": "Debug (Edge)",
59+
"configurations": ["Launch App (Edge)", "Start"],
60+
"preLaunchTask": "Start Teams App Locally",
61+
"presentation": {
62+
"group": "all",
63+
"order": 1
64+
},
65+
"stopAll": true
66+
},
67+
{
68+
"name": "Debug (Chrome)",
69+
"configurations": ["Launch App (Chrome)" , "Start"],
70+
"preLaunchTask": "Start Teams App Locally",
71+
"presentation": {
72+
"group": "all",
73+
"order": 2
74+
},
75+
"stopAll": true
76+
}
77+
]
78+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// This file is automatically generated by M365 Agents Toolkit.
2+
// The teamsfx tasks defined in this file require M365 Agents Toolkit version >= 5.0.0.
3+
// See https://aka.ms/teamsfx-tasks for details on how to customize each task.
4+
{
5+
"version": "2.0.0",
6+
"tasks": [
7+
{
8+
"label": "Start Teams App Locally",
9+
"dependsOn": [
10+
"Validate prerequisites",
11+
"Start local tunnel",
12+
"Provision",
13+
"Deploy",
14+
"setup-env"
15+
],
16+
"dependsOrder": "sequence"
17+
},
18+
{
19+
"label": "Validate prerequisites",
20+
"type": "teamsfx",
21+
"command": "debug-check-prerequisites",
22+
"args": {
23+
"prerequisites": [
24+
"python",
25+
"m365Account",
26+
"portOccupancy"
27+
],
28+
"portOccupancy": [
29+
3978
30+
]
31+
}
32+
},
33+
{
34+
"label": "Start local tunnel",
35+
"type": "teamsfx",
36+
"command": "debug-start-local-tunnel",
37+
"args": {
38+
"type": "dev-tunnel",
39+
"ports": [
40+
{
41+
"portNumber": 3978,
42+
"protocol": "http",
43+
"access": "public",
44+
"writeToEnvironmentFile": {
45+
"endpoint": "BOT_ENDPOINT",
46+
"domain": "BOT_DOMAIN"
47+
}
48+
}
49+
],
50+
"env": "local"
51+
},
52+
"isBackground": true,
53+
"problemMatcher": "$teamsfx-local-tunnel-watch"
54+
},
55+
{
56+
"label": "Provision",
57+
"type": "teamsfx",
58+
"command": "provision",
59+
"args": {
60+
"env": "local"
61+
}
62+
},
63+
{
64+
"label": "Deploy",
65+
"type": "teamsfx",
66+
"command": "deploy",
67+
"args": {
68+
"env": "local"
69+
}
70+
},
71+
{
72+
"label": "setup-env",
73+
"type": "shell",
74+
"command": "uv sync",
75+
"problemMatcher": [],
76+
"group": {
77+
"kind": "build",
78+
"isDefault": true
79+
}
80+
}
81+
]
82+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# M365 Agents Toolkit Configuration: Oauth
2+
3+
Use this if you want to enable user authentication in your Teams application.
4+
5+
## How to update scopes
6+
7+
1. In the `aad.manifest.json` file, update the `requiredResourceAccess` list to add the required scopes.
8+
9+
2. In the `infra/botRegistration/azurebot.bicep` file, under the `botServicesMicrosoftGraphConnection` resource, update the `properties.scopes` string to be a comma-delimeted list of the required scopes.
10+
11+
### Example
12+
13+
If you want to add the `People.Read.All` and `User.ReadBasic.All` scopes.
14+
15+
1. Your `requiredResourceAccess` property should look like:
16+
17+
```json
18+
"requiredResourceAccess": [
19+
{
20+
"resourceAppId": "Microsoft Graph",
21+
"resourceAccess": [
22+
{
23+
"id": "People.Read.All",
24+
"type": "Scope"
25+
}
26+
]
27+
},
28+
{
29+
"resourceAppId": "Microsoft Graph",
30+
"resourceAccess": [
31+
{
32+
"id": "User.ReadBasic.All",
33+
"type": "Scope"
34+
}
35+
]
36+
},
37+
]
38+
```
39+
40+
2. Update the `properties.scopes` to be `People.Read.All,User.ReadBasic.All`.
41+
42+
Refer [here](https://learn.microsoft.com/en-us/graph/permissions-reference) for in-depth Microsoft Graph permissions reference.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"id": "$\{{AAD_APP_OBJECT_ID}}",
3+
"appId": "$\{{BOT_ID}}",
4+
"name": "{{ toPascalCase name }}$\{{APP_NAME_SUFFIX}}",
5+
"accessTokenAcceptedVersion": 2,
6+
"signInAudience": "AzureADMultipleOrgs",
7+
"optionalClaims": {
8+
"idToken": [],
9+
"accessToken": [
10+
{
11+
"name": "idtyp",
12+
"source": null,
13+
"essential": false,
14+
"additionalProperties": []
15+
}
16+
],
17+
"saml2Token": []
18+
},
19+
"requiredResourceAccess": [
20+
{
21+
"resourceAppId": "Microsoft Graph",
22+
"resourceAccess": [
23+
{
24+
"id": "User.Read",
25+
"type": "Scope"
26+
}
27+
]
28+
}
29+
],
30+
"oauth2Permissions": [
31+
{
32+
"adminConsentDescription": "Allows Teams to call the app's web APIs as the current user.",
33+
"adminConsentDisplayName": "Teams can access app's web APIs",
34+
"id": "$\{{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}",
35+
"isEnabled": true,
36+
"type": "User",
37+
"userConsentDescription": "Enable Teams to call this app's web APIs with the same rights that you have",
38+
"userConsentDisplayName": "Teams can access app's web APIs and make requests on your behalf",
39+
"value": "access_as_user"
40+
}
41+
],
42+
"preAuthorizedApplications": [
43+
{
44+
"appId": "1fec8e78-bce4-4aaf-ab1b-5451cc387264",
45+
"permissionIds": [
46+
"$\{{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
47+
]
48+
},
49+
{
50+
"appId": "5e3ce6c0-2b1f-4285-8d4b-75ee78787346",
51+
"permissionIds": [
52+
"$\{{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}"
53+
]
54+
}
55+
],
56+
"identifierUris": [
57+
"api://botid-$\{{BOT_ID}}"
58+
],
59+
"replyUrlsWithType": [
60+
{
61+
"url": "https://token.botframework.com/.auth/web/redirect",
62+
"type": "Web"
63+
}
64+
]
65+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
@maxLength(20)
2+
@minLength(4)
3+
@description('Used to generate names for all resources in this file')
4+
param resourceBaseName string
5+
6+
@description('Required when create Azure Bot service')
7+
param botAadAppClientId string
8+
9+
@secure()
10+
@description('Required by Bot Framework package in your bot project')
11+
param botAadAppClientSecret string
12+
13+
@maxLength(42)
14+
param botDisplayName string
15+
16+
param botAppDomain string
17+
param oauthConnectionName string
18+
param tenantId string
19+
20+
module azureBotRegistration './botRegistration/azurebot.bicep' = {
21+
name: 'Azure-Bot-registration'
22+
params: {
23+
resourceBaseName: resourceBaseName
24+
botAadAppClientId: botAadAppClientId
25+
botAppDomain: botAppDomain
26+
botDisplayName: botDisplayName
27+
botAddAppClientSecret: botAadAppClientSecret
28+
oauthConnectionName: oauthConnectionName
29+
tenantId: tenantId
30+
}
31+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
3+
"contentVersion": "1.0.0.0",
4+
"parameters": {
5+
"resourceBaseName": {
6+
"value": "bot-$\{{RESOURCE_SUFFIX}}-$\{{TEAMSFX_ENV}}"
7+
},
8+
"botAadAppClientId": {
9+
"value": "$\{{BOT_ID}}"
10+
},
11+
"botAadAppClientSecret": {
12+
"value": "$\{{SECRET_BOT_PASSWORD}}"
13+
},
14+
"botDisplayName": {
15+
"value": "{{ toPascalCase name }}-$\{{TEAMSFX_ENV}}"
16+
},
17+
"botAppDomain": {
18+
"value": "$\{{BOT_DOMAIN}}"
19+
},
20+
"oauthConnectionName": {
21+
"value": "$\{{OAUTH_CONNECTION_NAME}}"
22+
},
23+
"tenantId": {
24+
"value": "$\{{AAD_APP_TENANT_ID}}"
25+
}
26+
}
27+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
@maxLength(20)
2+
@minLength(4)
3+
@description('Used to generate names for all resources in this file')
4+
param resourceBaseName string
5+
6+
@maxLength(42)
7+
param botDisplayName string
8+
9+
param botServiceName string = resourceBaseName
10+
param botServiceSku string = 'F0'
11+
param botAadAppClientId string
12+
param botAppDomain string
13+
param oauthConnectionName string
14+
param tenantId string
15+
16+
@secure()
17+
param botAddAppClientSecret string
18+
19+
// Register your web service as a bot with the Bot Framework
20+
resource botService 'Microsoft.BotService/botServices@2021-03-01' = {
21+
kind: 'azurebot'
22+
location: 'global'
23+
name: botServiceName
24+
properties: {
25+
displayName: botDisplayName
26+
endpoint: 'https://${botAppDomain}/api/messages'
27+
msaAppId: botAadAppClientId
28+
msaAppType: 'SingleTenant'
29+
msaAppTenantId: tenantId
30+
}
31+
sku: {
32+
name: botServiceSku
33+
}
34+
}
35+
36+
// Connect the bot service to Microsoft Teams
37+
resource botServiceMsTeamsChannel 'Microsoft.BotService/botServices/channels@2021-03-01' = {
38+
parent: botService
39+
location: 'global'
40+
name: 'MsTeamsChannel'
41+
properties: {
42+
channelName: 'MsTeamsChannel'
43+
}
44+
}
45+
46+
resource botServicesMicrosoftGraphConnection 'Microsoft.BotService/botServices/connections@2022-09-15' = {
47+
parent: botService
48+
name: oauthConnectionName
49+
location: 'global'
50+
properties: {
51+
serviceProviderDisplayName: 'Azure Active Directory v2'
52+
serviceProviderId: '30dd229c-58e3-4a48-bdfd-91ec48eb906c'
53+
clientId: botAadAppClientId
54+
clientSecret: botAddAppClientSecret
55+
scopes: 'User.Read'
56+
parameters: [
57+
{
58+
key: 'tenantID'
59+
value: 'common'
60+
}
61+
{
62+
key: 'tokenExchangeUrl'
63+
value: 'api://botid-${botAadAppClientId}'
64+
}
65+
]
66+
}
67+
}

0 commit comments

Comments
 (0)