Skip to content

Commit 9262456

Browse files
committed
escape usernames while launching servers
This will let authenticated binderhubs deal with usernames which aren't escaped. Example: 'User 1', '[email protected]'
1 parent 4b41dc2 commit 9262456

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

binderhub/launcher.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import random
77
import re
88
import string
9-
from urllib.parse import urlparse
9+
from urllib.parse import urlparse, quote
1010
import uuid
1111
import os
1212

@@ -161,11 +161,12 @@ async def launch(self, image, username, server_name='', repo_url='', extra_args=
161161
"""
162162
# TODO: validate the image argument?
163163

164+
escaped_username = quote(username, safe='@~')
164165
if self.create_user:
165166
# create a new user
166167
app_log.info("Creating user %s for image %s", username, image)
167168
try:
168-
await self.api_request('users/%s' % username, body=b'', method='POST')
169+
await self.api_request('users/%s' % escaped_username, body=b'', method='POST')
169170
except HTTPError as e:
170171
if e.response:
171172
body = e.response.body
@@ -178,13 +179,13 @@ async def launch(self, image, username, server_name='', repo_url='', extra_args=
178179
elif server_name == '':
179180
# authentication is enabled but not named servers
180181
# check if user has a running server ('')
181-
user_data = await self.get_user_data(username)
182+
user_data = await self.get_user_data(escaped_username)
182183
if server_name in user_data['servers']:
183184
raise web.HTTPError(409, "User %s already has a running server." % username)
184185
elif self.named_server_limit_per_user > 0:
185186
# authentication is enabled with named servers
186187
# check if user has already reached to the limit of named servers
187-
user_data = await self.get_user_data(username)
188+
user_data = await self.get_user_data(escaped_username)
188189
len_named_spawners = len([s for s in user_data['servers'] if s != ''])
189190
if self.named_server_limit_per_user <= len_named_spawners:
190191
raise web.HTTPError(
@@ -213,7 +214,7 @@ async def launch(self, image, username, server_name='', repo_url='', extra_args=
213214
app_log.info("Starting server%s for user %s with image %s", _server_name, username, image)
214215
try:
215216
resp = await self.api_request(
216-
'users/{}/servers/{}'.format(username, server_name),
217+
'users/{}/servers/{}'.format(escaped_username, server_name),
217218
method='POST',
218219
body=json.dumps(data).encode('utf8'),
219220
)
@@ -222,7 +223,7 @@ async def launch(self, image, username, server_name='', repo_url='', extra_args=
222223
# We wait for it!
223224
# NOTE: This ends up being about ten minutes
224225
for i in range(64):
225-
user_data = await self.get_user_data(username)
226+
user_data = await self.get_user_data(escaped_username)
226227
if user_data['servers'][server_name]['ready']:
227228
break
228229
if not user_data['servers'][server_name]['pending']:
@@ -244,5 +245,5 @@ async def launch(self, image, username, server_name='', repo_url='', extra_args=
244245
format(_server_name, username, e, body))
245246
raise web.HTTPError(500, "Failed to launch image %s" % image)
246247

247-
data['url'] = self.hub_url + 'user/%s/%s' % (username, server_name)
248+
data['url'] = self.hub_url + 'user/%s/%s' % (escaped_username, server_name)
248249
return data

0 commit comments

Comments
 (0)