mirror of
https://github.com/Sea-Haven-Industries/meal-order-manager.git
synced 2026-09-30 08:53:13 +00:00
fix(ci): satisfy PR policy and authorizer trust constraints
Move weekly-menu step expressions into env blocks, terraform-fmt SES alignment, and pin API Gateway authorizer invoke role assume conditions.
This commit is contained in:
parent
3906ad1885
commit
1f67543f16
2 changed files with 44 additions and 17 deletions
43
.github/workflows/weekly-menu.yml
vendored
43
.github/workflows/weekly-menu.yml
vendored
|
|
@ -28,8 +28,9 @@ jobs:
|
|||
steps:
|
||||
- name: Timezone guard
|
||||
if: github.event_name == 'schedule'
|
||||
env:
|
||||
CRON: ${{ github.event.schedule }}
|
||||
run: |
|
||||
CRON="${{ github.event.schedule }}"
|
||||
OFFSET=$(TZ='America/New_York' date +%z)
|
||||
echo "Cron: $CRON | Eastern offset: $OFFSET"
|
||||
if { [ "$OFFSET" = "-0400" ] && [ "$CRON" = "30 12 * * 1" ]; } || \
|
||||
|
|
@ -92,9 +93,10 @@ jobs:
|
|||
- name: Get discount settings
|
||||
if: env.SKIP_RUN != 'true'
|
||||
id: discount
|
||||
env:
|
||||
API_URL: ${{ steps.stack.outputs.api_url }}
|
||||
run: |
|
||||
SETTINGS=$(python3 scripts/upload_menu.py settings \
|
||||
--api-url "${{ steps.stack.outputs.api_url }}")
|
||||
SETTINGS=$(python3 scripts/upload_menu.py settings --api-url "$API_URL")
|
||||
BULK=$(python3 -c 'import json,sys; print(json.loads(sys.argv[1])["bulk_discount_percent"])' "$SETTINGS")
|
||||
SUBSIDY=$(python3 -c 'import json,sys; print(json.loads(sys.argv[1])["company_subsidy_percent"])' "$SETTINGS")
|
||||
echo "bulk_discount=$BULK" >> "$GITHUB_OUTPUT"
|
||||
|
|
@ -112,42 +114,53 @@ jobs:
|
|||
echo "Google client ID is required for cloud form generation" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "client_id=$GOOGLE_CLIENT_ID" >> $GITHUB_OUTPUT
|
||||
echo "client_id=$GOOGLE_CLIENT_ID" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Generate order form
|
||||
if: env.SKIP_RUN != 'true'
|
||||
env:
|
||||
API_URL: ${{ steps.stack.outputs.api_url }}
|
||||
BULK_DISCOUNT: ${{ steps.discount.outputs.bulk_discount }}
|
||||
COMPANY_SUBSIDY: ${{ steps.discount.outputs.company_subsidy }}
|
||||
GOOGLE_CLIENT_ID: ${{ steps.google.outputs.client_id }}
|
||||
run: |
|
||||
python3 src/server/generate_form.py \
|
||||
--api-url "${{ steps.stack.outputs.api_url }}" \
|
||||
--bulk-discount "${{ steps.discount.outputs.bulk_discount }}" \
|
||||
--company-subsidy "${{ steps.discount.outputs.company_subsidy }}" \
|
||||
--google-client-id "${{ steps.google.outputs.client_id }}"
|
||||
--api-url "$API_URL" \
|
||||
--bulk-discount "$BULK_DISCOUNT" \
|
||||
--company-subsidy "$COMPANY_SUBSIDY" \
|
||||
--google-client-id "$GOOGLE_CLIENT_ID"
|
||||
|
||||
- name: Publish menu through API
|
||||
if: env.SKIP_RUN != 'true'
|
||||
run: |
|
||||
python3 scripts/upload_menu.py publish \
|
||||
--api-url "${{ steps.stack.outputs.api_url }}"
|
||||
env:
|
||||
API_URL: ${{ steps.stack.outputs.api_url }}
|
||||
run: python3 scripts/upload_menu.py publish --api-url "$API_URL"
|
||||
|
||||
- name: Upload form to S3
|
||||
if: env.SKIP_RUN != 'true'
|
||||
env:
|
||||
FORM_BUCKET: ${{ steps.stack.outputs.form_bucket }}
|
||||
run: |
|
||||
WEEK=$(date +%Y-W%U)
|
||||
aws s3 cp "output/order-form-$WEEK.html" \
|
||||
"s3://${{ steps.stack.outputs.form_bucket }}/index.html" \
|
||||
"s3://${FORM_BUCKET}/index.html" \
|
||||
--content-type "text/html" \
|
||||
--cache-control "no-cache"
|
||||
aws s3 cp "output/order-form-$WEEK.html" \
|
||||
"s3://${{ steps.stack.outputs.form_bucket }}/archive/$WEEK.html" \
|
||||
"s3://${FORM_BUCKET}/archive/$WEEK.html" \
|
||||
--content-type "text/html"
|
||||
|
||||
- name: Invalidate CloudFront cache
|
||||
if: env.SKIP_RUN != 'true'
|
||||
env:
|
||||
DIST_ID: ${{ steps.stack.outputs.dist_id }}
|
||||
run: |
|
||||
aws cloudfront create-invalidation \
|
||||
--distribution-id "${{ steps.stack.outputs.dist_id }}" \
|
||||
--distribution-id "$DIST_ID" \
|
||||
--paths "/index.html"
|
||||
|
||||
- name: Notify Slack
|
||||
if: env.SKIP_RUN != 'true'
|
||||
run: python3 scripts/notify_slack.py "${{ steps.stack.outputs.form_url }}"
|
||||
env:
|
||||
FORM_URL: ${{ steps.stack.outputs.form_url }}
|
||||
run: python3 scripts/notify_slack.py "$FORM_URL"
|
||||
|
|
|
|||
|
|
@ -174,6 +174,8 @@ resource "aws_iam_role_policy" "admin_authorizer" {
|
|||
|
||||
# Role API Gateway assumes to invoke the authorizer Lambda. The authorizer has
|
||||
# no resource policy of its own; this identity-based grant is the only path.
|
||||
# SourceAccount + execute-api ArnLike close the confused-deputy window without
|
||||
# pinning the authorizer id (that would cycle: authorizer needs this role).
|
||||
data "aws_iam_policy_document" "apigateway_assume" {
|
||||
statement {
|
||||
effect = "Allow"
|
||||
|
|
@ -183,6 +185,18 @@ data "aws_iam_policy_document" "apigateway_assume" {
|
|||
type = "Service"
|
||||
identifiers = ["apigateway.amazonaws.com"]
|
||||
}
|
||||
|
||||
condition {
|
||||
test = "StringEquals"
|
||||
variable = "aws:SourceAccount"
|
||||
values = [local.account_id]
|
||||
}
|
||||
|
||||
condition {
|
||||
test = "ArnLike"
|
||||
variable = "aws:SourceArn"
|
||||
values = ["arn:aws:execute-api:${var.aws_region}:${local.account_id}:${aws_apigatewayv2_api.order_api.id}/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -391,8 +405,8 @@ data "aws_iam_policy_document" "email_report" {
|
|||
# Scope SendRawEmail to the verified sender domain/identity rather than "*".
|
||||
# SES still enforces verification; IAM pins the From identity ARNs.
|
||||
statement {
|
||||
sid = "SendPayrollReport"
|
||||
effect = "Allow"
|
||||
sid = "SendPayrollReport"
|
||||
effect = "Allow"
|
||||
actions = ["ses:SendRawEmail"]
|
||||
resources = [
|
||||
"arn:aws:ses:${var.aws_region}:${local.account_id}:identity/${var.sender_email}",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue