Authored-By: @architect <architect@fritzlab.net>
This commit is contained in:
@@ -8,6 +8,7 @@ import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from urllib.error import HTTPError, URLError
|
||||
from urllib.request import Request, urlopen
|
||||
@@ -169,6 +170,41 @@ def publication_aws_env(artifact, credential_env_names=None):
|
||||
return aws_env
|
||||
|
||||
|
||||
def configure_cors(bucket, origins, endpoint, aws_env):
|
||||
"""Reconcile read-only browser access without exposing publication credentials."""
|
||||
if origins is None:
|
||||
return
|
||||
if not origins:
|
||||
run([
|
||||
"aws", "--endpoint-url", endpoint, "s3api", "delete-bucket-cors",
|
||||
"--bucket", bucket,
|
||||
], env=aws_env)
|
||||
return
|
||||
config = {
|
||||
"CORSRules": [{
|
||||
"AllowedOrigins": origins,
|
||||
"AllowedMethods": ["GET", "HEAD"],
|
||||
"AllowedHeaders": ["*"],
|
||||
"ExposeHeaders": ["ETag"],
|
||||
"MaxAgeSeconds": 3600,
|
||||
}],
|
||||
}
|
||||
with tempfile.NamedTemporaryFile("w", suffix=".json", encoding="utf-8") as handle:
|
||||
json.dump(config, handle)
|
||||
handle.flush()
|
||||
run([
|
||||
"aws", "--endpoint-url", endpoint, "s3api", "put-bucket-cors",
|
||||
"--bucket", bucket, "--cors-configuration", f"file://{handle.name}",
|
||||
], env=aws_env)
|
||||
|
||||
|
||||
def configure_artifact_cors(artifact, credential_env_names=None):
|
||||
configure_cors(
|
||||
artifact["bucket"], artifact["cors_origins"], artifact["s3_endpoint"],
|
||||
publication_aws_env(artifact, credential_env_names),
|
||||
)
|
||||
|
||||
|
||||
def publish_route_immutables(artifact, route, site_dir, credential_env_names=None):
|
||||
"""Publish one route's immutable partitions during the global preflight."""
|
||||
html_dir = site_dir / artifact["build_dir"]
|
||||
@@ -460,6 +496,11 @@ def deploy_static(site_name, site_dir, action_dir, token, cfg):
|
||||
publish_route_immutables(
|
||||
artifact_by_name[route["artifact"]], route, site_dir, credential_env_names,
|
||||
)
|
||||
# Reconcile every browser-read policy before publishing mutable content.
|
||||
# A CORS failure therefore cannot leave a new channel pointing at a release
|
||||
# whose cross-origin assets browsers cannot consume.
|
||||
for artifact in cfg["artifacts"]:
|
||||
configure_artifact_cors(artifact, credential_env_names)
|
||||
for route in cfg["routes"]:
|
||||
s3_sync(
|
||||
artifact_by_name[route["artifact"]], route, site_dir, credential_env_names,
|
||||
|
||||
Reference in New Issue
Block a user