Skip to content

Commit 09223fc

Browse files
committed
Updated resource provisioning script with creation and assignment of Oauth roles associated with app registrations governing our function app and static website
1 parent 0eab1b7 commit 09223fc

File tree

3 files changed

+93
-13
lines changed

3 files changed

+93
-13
lines changed

README.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ Once the CSV has been uploaded to the storage blob, another, blob-triggered Azur
66
The computed statistics are then stored in a new blob container, which is used to serve the results to the user.
77
These two functions are defined in the python script [function_app.py](hvalfangst_function/function_app.py) - which is the main entrypoint of our Azure Function App instance.
88

9+
The SPA is protected with Oauth2.0 authorization code flow with PKCE and OIDC. The user is redirected to the Azure AD login page, where they must authenticate before being redirected back to the SPA.
10+
11+
912
The associated Azure infrastructure is deployed with a script (more on that below).
1013

1114
A branch-triggered pipeline has been set up to deploy our code to the respective Azure resources using a GitHub Actions Workflows [script](.github/workflows/deploy_to_azure.yml).
@@ -24,7 +27,7 @@ Thus, deploying the website is simply a matter of uploading the static files to
2427

2528
## Allocate resources
2629

27-
The shell script [allocate_resources](infra/allocate_resources.sh) creates Azure resources using the Azure CLI and a
30+
The shell script [allocate_resources](infra/allocate_resources.sh) creates Azure resources using the Azure CLI in conjunction with a
2831
[Bicep](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview?tabs=bicep) template [file](infra/main.bicep).
2932

3033
It will create the following hierarchy of resources:
@@ -56,4 +59,13 @@ As may be observed in the [script](.github/workflows/deploy_to_azure.yml), these
5659
- **AZURE_TENANT_ID**: Used to authenticate the service principal in order to deploy the static web app
5760
- **PUBLISH_PROFILE**: Used to deploy our two functions to the Azure Function App
5861

59-
![img_1.png](images/img_1.png)
62+
![secrets.png](images/secrets.png)
63+
64+
## Usage
65+
After provisioning resources, setting up secrets, and pushing the code to the repository, one
66+
may access the static web app by navigating to the following URL:
67+
68+
```plaintext
69+
https://<storage_account_name>.z6.web.core.windows.net
70+
```
71+
File renamed without changes.

infra/allocate_resources.sh

Lines changed: 79 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -108,37 +108,105 @@ if [ $? -ne 0 ]; then
108108
exit 1
109109
fi
110110

111-
# Set up app registration for function app
111+
112+
# Set up app registration for the function app
112113
echo -e "${YELLOW}Setting up app registration for function app...${RESET}"
113114
FUNCTION_APP_CLIENT_ID=$(az ad app create \
114115
--display-name "hvalfangst-function-app" \
116+
--identifier-uris "api://hvalfangst-function-app" \
115117
--query appId -o tsv)
116-
117118
if [ $? -ne 0 ] || [ -z "$FUNCTION_APP_CLIENT_ID" ]; then
118119
echo -e "${RED}Failed to set up app registration or retrieve the app ID.${RESET}"
119120
exit 1
120121
fi
121122

122-
# Set up app settings for the function app
123-
echo -e "${YELLOW}Setting up app settings for function app...${RESET}"
124-
az functionapp config appsettings set \
125-
--name ${FUNCTION_APP_NAME} \
126-
--resource-group ${RESOURCE_GROUP} \
127-
--settings TENANT_ID=${TENANT_ID} FUNCTION_APP_CLIENT_ID=${FUNCTION_APP_CLIENT_ID}
128-
if [ $? -ne 0 ]; then
129-
echo -e "${RED}Failed to set up app settings for function app.${RESET}"
123+
# Get the object ID of the app registration
124+
FUNCTION_APP_OBJECT_ID=$(az ad app show --id $FUNCTION_APP_CLIENT_ID --query id -o tsv)
125+
126+
# Get an access token for the Microsoft Graph API
127+
TOKEN=$(az account get-access-token --resource https://graph.microsoft.com --query accessToken -o tsv)
128+
if [ $? -ne 0 ] || [ -z "$TOKEN" ]; then
129+
echo -e "${RED}Failed to get access token for Microsoft Graph API.${RESET}"
130130
exit 1
131131
fi
132132

133+
# Generate UUIDs for the permissions
134+
CSV_READER_UUID=$(python -c 'import uuid; print(str(uuid.uuid4()))')
135+
CSV_WRITER_UUID=$(python -c 'import uuid; print(str(uuid.uuid4()))')
136+
137+
# Add permissions to the app registration by calling the Microsoft Graph API with a PATCH request
138+
echo -e "${YELLOW}Creating scopes for the Function App...${RESET}"
139+
curl -X PATCH -H "Authorization: Bearer $TOKEN" \
140+
-H "Content-Type: application/json" \
141+
-d "{
142+
\"api\": {
143+
\"oauth2PermissionScopes\": [
144+
{
145+
\"id\": \"$CSV_READER_UUID\",
146+
\"adminConsentDescription\": \"Allows downloading of CSV files\",
147+
\"adminConsentDisplayName\": \"Allows downloading of CSV files\",
148+
\"isEnabled\": true,
149+
\"type\": \"Admin\",
150+
\"value\": \"Csv.Reader\"
151+
},
152+
{
153+
\"id\": \"$CSV_WRITER_UUID\",
154+
\"adminConsentDescription\": \"Allows uploading of CSV files\",
155+
\"adminConsentDisplayName\": \"Allows uploading of CSV files\",
156+
\"isEnabled\": true,
157+
\"type\": \"Admin\",
158+
\"value\": \"Csv.Writer\"
159+
}
160+
]
161+
}
162+
}" \
163+
"https://graph.microsoft.com/v1.0/applications/$FUNCTION_APP_OBJECT_ID"
164+
133165
# Set up app registration for the static web app
134166
echo -e "${YELLOW}Setting up app registration for static web app...${RESET}"
135167
STATIC_WEB_APP_CLIENT_ID=$(az ad app create \
136168
--display-name "hvalfangst-static-web-app" \
169+
--web-redirect-uris "http://localhost:3000" \
137170
--query appId -o tsv)
138-
139171
if [ $? -ne 0 ] || [ -z "STATIC_WEB_APP_CLIENT_ID" ]; then
140172
echo -e "${RED}Failed to set up app registration or retrieve the app ID.${RESET}"
141173
exit 1
142174
fi
143175

176+
STATIC_WEB_APP_OBJECT_ID=$(az ad app show --id $STATIC_WEB_APP_CLIENT_ID --query id -o tsv)
177+
if [ $? -ne 0 ] || [ -z "$STATIC_WEB_APP_OBJECT_ID" ]; then
178+
echo -e "${RED}Failed to retrieve the object ID of the static web app registration.${RESET}"
179+
exit 1
180+
fi
181+
182+
# Add permissions to the app registration by calling the Microsoft Graph API with a PATCH request
183+
echo -e "${YELLOW}Assigning permissions from Function App to Static Website${RESET}"
184+
curl -X PATCH -H "Authorization: Bearer $TOKEN" \
185+
-H "Content-Type: application/json" \
186+
-d "{
187+
\"requiredResourceAccess\": [
188+
{
189+
\"resourceAppId\": \"$FUNCTION_APP_CLIENT_ID\",
190+
\"resourceAccess\": [
191+
{
192+
\"id\": \"$CSV_WRITER_UUID\",
193+
\"type\": \"Scope\"
194+
}
195+
]
196+
}
197+
]
198+
}" \
199+
"https://graph.microsoft.com/v1.0/applications/$STATIC_WEB_APP_OBJECT_ID"
200+
201+
# Set up app settings for the function app
202+
echo -e "${YELLOW}Setting up app settings for function app...${RESET}"
203+
az functionapp config appsettings set \
204+
--name ${FUNCTION_APP_NAME} \
205+
--resource-group ${RESOURCE_GROUP} \
206+
--settings TENANT_ID=${TENANT_ID} FUNCTION_APP_CLIENT_ID=${FUNCTION_APP_CLIENT_ID}
207+
if [ $? -ne 0 ]; then
208+
echo -e "${RED}Failed to set up app settings for function app.${RESET}"
209+
exit 1
210+
fi
211+
144212
echo -e "${GREEN}All resources have been provisioned.${RESET}"

0 commit comments

Comments
 (0)