Skip to content

Commit d654b8a

Browse files
diewdurbin
andauthored
Conditional includes (#17794)
* Split authed/unauthed includes by route * Only disallow authed includes with robots.txt * Only fetch authed includes if we are authed * Update warehouse/static/js/warehouse/utils/html-include.js Whoopsie Co-authored-by: Ee Durbin <[email protected]> * Update warehouse/static/js/warehouse/utils/html-include.js Whoopsie. * Handle both full URLs and paths --------- Co-authored-by: Ee Durbin <[email protected]>
1 parent 51cd950 commit d654b8a

File tree

8 files changed

+52
-28
lines changed

8 files changed

+52
-28
lines changed

tests/functional/manage/test_views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ def test_changing_password_succeeds(self, webtest, socket_enabled):
107107
change_password_form.submit().follow(status=HTTPStatus.OK)
108108

109109
# Request the JavaScript-enabled flash messages directly to get the message
110-
resp = webtest.get("/_includes/flash-messages/", status=HTTPStatus.OK)
110+
resp = webtest.get("/_includes/authed/flash-messages/", status=HTTPStatus.OK)
111111
success_message = resp.html.find("span", {"class": "notification-bar__message"})
112112
assert success_message.text == "Password updated"
113113

tests/functional/test_basic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def test_robots_txt(app_config, domain, indexable):
3232
"User-agent: *\n"
3333
"Disallow: /simple/\n"
3434
"Disallow: /packages/\n"
35-
"Disallow: /_includes/\n"
35+
"Disallow: /_includes/authed/\n"
3636
"Disallow: /pypi/*/json\n"
3737
"Disallow: /pypi/*/*/json\n"
3838
"Disallow: /pypi*?\n"

tests/unit/banners/test_init.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def test_includeme():
2626
assert config.add_route.calls == [
2727
pretend.call(
2828
"includes.db-banners",
29-
"/_includes/notification-banners/",
29+
"/_includes/unauthed/notification-banners/",
3030
domain="pypi",
3131
),
3232
]

tests/unit/test_routes.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,65 +84,67 @@ def add_redirect_rule(*args, **kwargs):
8484
pretend.call("bucket.sitemap.xml", "/{bucket}.sitemap.xml", domain=warehouse),
8585
pretend.call(
8686
"includes.current-user-indicator",
87-
"/_includes/current-user-indicator/",
87+
"/_includes/authed/current-user-indicator/",
8888
domain=warehouse,
8989
),
9090
pretend.call(
91-
"includes.flash-messages", "/_includes/flash-messages/", domain=warehouse
91+
"includes.flash-messages",
92+
"/_includes/authed/flash-messages/",
93+
domain=warehouse,
9294
),
9395
pretend.call(
9496
"includes.session-notifications",
95-
"/_includes/session-notifications/",
97+
"/_includes/authed/session-notifications/",
9698
domain=warehouse,
9799
),
98100
pretend.call(
99101
"includes.current-user-profile-callout",
100-
"/_includes/current-user-profile-callout/{username}",
102+
"/_includes/authed/current-user-profile-callout/{username}",
101103
factory="warehouse.accounts.models:UserFactory",
102104
traverse="/{username}",
103105
domain=warehouse,
104106
),
105107
pretend.call(
106108
"includes.edit-project-button",
107-
"/_includes/edit-project-button/{project_name}",
109+
"/_includes/authed/edit-project-button/{project_name}",
108110
factory="warehouse.packaging.models:ProjectFactory",
109111
traverse="/{project_name}",
110112
domain=warehouse,
111113
),
112114
pretend.call(
113115
"includes.profile-actions",
114-
"/_includes/profile-actions/{username}",
116+
"/_includes/authed/profile-actions/{username}",
115117
factory="warehouse.accounts.models:UserFactory",
116118
traverse="/{username}",
117119
domain=warehouse,
118120
),
119121
pretend.call(
120122
"includes.profile-public-email",
121-
"/_includes/profile-public-email/{username}",
123+
"/_includes/authed/profile-public-email/{username}",
122124
factory="warehouse.accounts.models:UserFactory",
123125
traverse="/{username}",
124126
domain=warehouse,
125127
),
126128
pretend.call(
127129
"includes.sidebar-sponsor-logo",
128-
"/_includes/sidebar-sponsor-logo/",
130+
"/_includes/unauthed/sidebar-sponsor-logo/",
129131
domain=warehouse,
130132
),
131133
pretend.call(
132134
"includes.administer-project-include",
133-
"/_includes/administer-project-include/{project_name}",
135+
"/_includes/authed/administer-project-include/{project_name}",
134136
domain=warehouse,
135137
),
136138
pretend.call(
137139
"includes.administer-user-include",
138-
"/_includes/administer-user-include/{user_name}",
140+
"/_includes/authed/administer-user-include/{user_name}",
139141
factory="warehouse.accounts.models:UserFactory",
140142
traverse="/{user_name}",
141143
domain=warehouse,
142144
),
143145
pretend.call(
144146
"includes.submit_malware_report",
145-
"/_includes/submit-malware-report/{project_name}",
147+
"/_includes/authed/submit-malware-report/{project_name}",
146148
factory="warehouse.packaging.models:ProjectFactory",
147149
traverse="/{project_name}",
148150
domain=warehouse,

warehouse/banners/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ def includeme(config):
1717
# route to async render banner messages
1818
config.add_route(
1919
"includes.db-banners",
20-
"/_includes/notification-banners/",
20+
"/_includes/unauthed/notification-banners/",
2121
domain=warehouse,
2222
)

warehouse/routes.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,65 +76,65 @@ def includeme(config):
7676
# HTML Snippets for including into other pages.
7777
config.add_route(
7878
"includes.current-user-indicator",
79-
"/_includes/current-user-indicator/",
79+
"/_includes/authed/current-user-indicator/",
8080
domain=warehouse,
8181
)
8282
config.add_route(
83-
"includes.flash-messages", "/_includes/flash-messages/", domain=warehouse
83+
"includes.flash-messages", "/_includes/authed/flash-messages/", domain=warehouse
8484
)
8585
config.add_route(
8686
"includes.session-notifications",
87-
"/_includes/session-notifications/",
87+
"/_includes/authed/session-notifications/",
8888
domain=warehouse,
8989
)
9090
config.add_route(
9191
"includes.current-user-profile-callout",
92-
"/_includes/current-user-profile-callout/{username}",
92+
"/_includes/authed/current-user-profile-callout/{username}",
9393
factory="warehouse.accounts.models:UserFactory",
9494
traverse="/{username}",
9595
domain=warehouse,
9696
)
9797
config.add_route(
9898
"includes.edit-project-button",
99-
"/_includes/edit-project-button/{project_name}",
99+
"/_includes/authed/edit-project-button/{project_name}",
100100
factory="warehouse.packaging.models:ProjectFactory",
101101
traverse="/{project_name}",
102102
domain=warehouse,
103103
)
104104
config.add_route(
105105
"includes.profile-actions",
106-
"/_includes/profile-actions/{username}",
106+
"/_includes/authed/profile-actions/{username}",
107107
factory="warehouse.accounts.models:UserFactory",
108108
traverse="/{username}",
109109
domain=warehouse,
110110
)
111111
config.add_route(
112112
"includes.profile-public-email",
113-
"/_includes/profile-public-email/{username}",
113+
"/_includes/authed/profile-public-email/{username}",
114114
factory="warehouse.accounts.models:UserFactory",
115115
traverse="/{username}",
116116
domain=warehouse,
117117
)
118118
config.add_route(
119119
"includes.sidebar-sponsor-logo",
120-
"/_includes/sidebar-sponsor-logo/",
120+
"/_includes/unauthed/sidebar-sponsor-logo/",
121121
domain=warehouse,
122122
)
123123
config.add_route(
124124
"includes.administer-project-include",
125-
"/_includes/administer-project-include/{project_name}",
125+
"/_includes/authed/administer-project-include/{project_name}",
126126
domain=warehouse,
127127
)
128128
config.add_route(
129129
"includes.administer-user-include",
130-
"/_includes/administer-user-include/{user_name}",
130+
"/_includes/authed/administer-user-include/{user_name}",
131131
factory="warehouse.accounts.models:UserFactory",
132132
traverse="/{user_name}",
133133
domain=warehouse,
134134
)
135135
config.add_route(
136136
"includes.submit_malware_report",
137-
"/_includes/submit-malware-report/{project_name}",
137+
"/_includes/authed/submit-malware-report/{project_name}",
138138
factory="warehouse.packaging.models:ProjectFactory",
139139
traverse="/{project_name}",
140140
domain=warehouse,

warehouse/static/js/warehouse/utils/html-include.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ const fetchOptions = {
1919
};
2020

2121
export default () => {
22+
// Check if we have an authenticated session
23+
let authed = document.cookie.split(";").some(
24+
v => v.trim().startsWith("user_id__insecure="),
25+
);
26+
2227
// Each HTML include will generate a promise, which we'll later use to wait
2328
// on once all the promises have been resolved.
2429
let promises = [];
@@ -31,7 +36,24 @@ export default () => {
3136
// data-html-include attribute and replace it's content with that. This uses
3237
// the new fetch() API which returns a Promise.
3338
elements.forEach((element) => {
34-
let p = fetch(element.getAttribute("data-html-include"), fetchOptions)
39+
let url = element.getAttribute("data-html-include");
40+
if (!authed) {
41+
// Don't fetch authed URLs if we aren't authenticated
42+
try {
43+
// Attempt to parse as full URL
44+
const pathname = new URL(url, "http://example.com").pathname;
45+
if (pathname.startsWith("/_includes/authed/")) {
46+
return;
47+
}
48+
} catch (e) {
49+
// If parsing fails, assume it's just a path
50+
if (url.startsWith("/_includes/authed/")) {
51+
return;
52+
}
53+
}
54+
}
55+
56+
let p = fetch(url, fetchOptions)
3557
.then(response => {
3658
if (response.ok) { return response.text(); }
3759
else { return ""; }

warehouse/templates/robots.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Disallow: /
66
{% else %}
77
Disallow: /simple/
88
Disallow: /packages/
9-
Disallow: /_includes/
9+
Disallow: /_includes/authed/
1010
Disallow: /pypi/*/json
1111
Disallow: /pypi/*/*/json
1212
Disallow: /pypi*?

0 commit comments

Comments
 (0)