diff --git a/config/settings/base.py b/config/settings/base.py index 7bb600ef..b2c35a16 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -614,6 +614,7 @@ CLOUDFLARE_API_EMAIL = env("CLOUDFLARE_API_EMAIL", default="") CLOUDFLARE_API_KEY = env("CLOUDFLARE_API_KEY", default="") CLOUDFLARE_API_ZONE = env("CLOUDFLARE_API_ZONE", default="") +CLOUDFLARE_HOSTS = env.list("CLOUDFLARE_HOSTS", default=[]) SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") diff --git a/config/settings/production.py b/config/settings/production.py index f4b8b619..568f72f3 100644 --- a/config/settings/production.py +++ b/config/settings/production.py @@ -4,7 +4,6 @@ # Third Party import sentry_sdk -from ipware import get_client_ip from sentry_sdk.integrations.celery import CeleryIntegration from sentry_sdk.integrations.django import DjangoIntegration from sentry_sdk.integrations.logging import LoggingIntegration @@ -74,6 +73,11 @@ # https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#settings AWS_S3_REGION_NAME = env("DJANGO_AWS_S3_REGION_NAME", default=None) +CLOUDFLARE_HOSTS = env.list( + "CLOUDFLARE_HOSTS", + default=["https://www.documentcloud.org", "https://embed.documentcloud.org"], +) + # STATIC # ------------------------ STATICFILES_STORAGE = "config.settings.production.StaticRootS3Boto3Storage" diff --git a/documentcloud/documents/models/document.py b/documentcloud/documents/models/document.py index e75d5be6..a61eccd4 100644 --- a/documentcloud/documents/models/document.py +++ b/documentcloud/documents/models/document.py @@ -702,9 +702,14 @@ def page_filter(text): return solr_document def invalidate_cache(self): - """Invalidate public CDN cache for this document's underlying file""" + """ + Invalidate public CDN cache for this document's underlying file, + plus frontend URLs in Cloudflare + """ logger.info("Invalidating cache for %s", self.pk) doc_path = self.doc_path[self.doc_path.index("/") :] + + # cloudfront distribution_id = settings.CLOUDFRONT_DISTRIBUTION_ID if distribution_id: # we want the doc path without the s3 bucket name @@ -716,15 +721,25 @@ def invalidate_cache(self): "CallerReference": str(uuid.uuid4()), }, ) + + # cloudflare cloudflare_email = settings.CLOUDFLARE_API_EMAIL cloudflare_key = settings.CLOUDFLARE_API_KEY cloudflare_zone = settings.CLOUDFLARE_API_ZONE - url = settings.PUBLIC_ASSET_URL + doc_path[1:] + asset_url = settings.PUBLIC_ASSET_URL + doc_path[1:] + + if self.access == Access.public: + public_urls = [ + host + self.get_absolute_url() for host in settings.CLOUDFLARE_HOSTS + ] + [asset_url] + else: + public_urls = [asset_url] + if cloudflare_zone: requests.post( "https://api.cloudflare.com/client/v4/zones/" f"{cloudflare_zone}/purge_cache", - json={"files": [url]}, + json={"files": public_urls}, headers={ "X-Auth-Email": cloudflare_email, "X-Auth-Key": cloudflare_key,