Repository: pypi/warehouse

Issue:
Migrate to Google Analytics 4
Universal Analytics will be going away.
> [Google Analytics 4](https://support.google.com/analytics/answer/10089681) is our next-generation measurement solution, and it's replacing Universal Analytics. On July 1, 2023, standard Universal Analytics properties will stop processing new hits. If you still rely on Universal Analytics, we recommend that you [prepare to use Google Analytics 4](https://support.google.com/analytics/answer/10759417) going forward.

From https://support.google.com/analytics/answer/11583528?hl=en

Places to examine:
- https://github.com/pypi/warehouse/blob/d0c6cee5b12c899a81c9fae484be714ca2f803db/warehouse/static/js/warehouse/utils/analytics.js
- https://github.com/pypi/warehouse/blob/d0c6cee5b12c899a81c9fae484be714ca2f803db/warehouse/templates/base.html#L138-L140
- https://github.com/pypi/warehouse/blob/d0c6cee5b12c899a81c9fae484be714ca2f803db/warehouse/csp.py#L109
- https://github.com/pypi/warehouse/blob/d0c6cee5b12c899a81c9fae484be714ca2f803db/warehouse/csp.py#L115-L116


Discussion:

Resolving patch:
diff --git a/warehouse/config.py b/warehouse/config.py
--- a/warehouse/config.py
+++ b/warehouse/config.py
@@ -194,6 +194,7 @@ def configure(settings=None):
     maybe_set(settings, "camo.key", "CAMO_KEY")
     maybe_set(settings, "docs.url", "DOCS_URL")
     maybe_set(settings, "ga.tracking_id", "GA_TRACKING_ID")
+    maybe_set(settings, "ga4.tracking_id", "GA4_TRACKING_ID")
     maybe_set(settings, "statuspage.url", "STATUSPAGE_URL")
     maybe_set(settings, "token.password.secret", "TOKEN_PASSWORD_SECRET")
     maybe_set(settings, "token.email.secret", "TOKEN_EMAIL_SECRET")
diff --git a/warehouse/csp.py b/warehouse/csp.py
--- a/warehouse/csp.py
+++ b/warehouse/csp.py
@@ -86,6 +86,9 @@ def includeme(config):
                 "connect-src": [
                     SELF,
                     "https://api.github.com/repos/",
+                    "https://*.google-analytics.com",
+                    "https://*.analytics.google.com",
+                    "https://*.googletagmanager.com",
                     "fastly-insights.com",
                     "*.fastly-insights.com",
                     "*.ethicalads.io",
@@ -106,14 +109,16 @@ def includeme(config):
                 "img-src": [
                     SELF,
                     config.registry.settings["camo.url"],
-                    "www.google-analytics.com",
+                    "https://*.google-analytics.com",
+                    "https://*.googletagmanager.com",
                     "*.fastly-insights.com",
                     "*.ethicalads.io",
                 ],
                 "script-src": [
                     SELF,
-                    "www.googletagmanager.com",
-                    "www.google-analytics.com",
+                    "https://*.googletagmanager.com",
+                    "https://www.google-analytics.com",  # Remove when disabling UA
+                    "https://ssl.google-analytics.com",  # Remove when disabling UA
                     "*.fastly-insights.com",
                     "*.ethicalads.io",
                     # Hash for v1.4.0 of ethicalads.min.js


Test patch:
diff --git a/tests/unit/test_csp.py b/tests/unit/test_csp.py
--- a/tests/unit/test_csp.py
+++ b/tests/unit/test_csp.py
@@ -217,6 +217,9 @@ def test_includeme():
                     "connect-src": [
                         "'self'",
                         "https://api.github.com/repos/",
+                        "https://*.google-analytics.com",
+                        "https://*.analytics.google.com",
+                        "https://*.googletagmanager.com",
                         "fastly-insights.com",
                         "*.fastly-insights.com",
                         "*.ethicalads.io",
@@ -232,14 +235,16 @@ def test_includeme():
                     "img-src": [
                         "'self'",
                         "camo.url.value",
-                        "www.google-analytics.com",
+                        "https://*.google-analytics.com",
+                        "https://*.googletagmanager.com",
                         "*.fastly-insights.com",
                         "*.ethicalads.io",
                     ],
                     "script-src": [
                         "'self'",
-                        "www.googletagmanager.com",
-                        "www.google-analytics.com",
+                        "https://*.googletagmanager.com",
+                        "https://www.google-analytics.com",
+                        "https://ssl.google-analytics.com",
                         "*.fastly-insights.com",
                         "*.ethicalads.io",
                         "'sha256-U3hKDidudIaxBDEzwGJApJgPEf2mWk6cfMWghrAa6i0='",