diff --git a/jupyterhub/tests/test_orm.py b/jupyterhub/tests/test_orm.py index d609b27b..e364e32f 100644 --- a/jupyterhub/tests/test_orm.py +++ b/jupyterhub/tests/test_orm.py @@ -73,6 +73,14 @@ def test_user(db): found = orm.User.find(db, 'badger') assert found is None +def test_user_escaping(db): + orm_user = orm.User(name='company\\user@company.com,\"quoted\"') + db.add(orm_user) + db.commit() + user = User(orm_user) + assert user.name == 'company\\user@company.com,\"quoted\"' + assert user.escaped_name == 'company%5Cuser@company.com%2C%22quoted%22' + assert user.json_escaped_name == 'company\\\\user@company.com,\\\"quoted\\\"' def test_tokens(db): user = orm.User(name='inara') diff --git a/jupyterhub/user.py b/jupyterhub/user.py index b929569c..9444d574 100644 --- a/jupyterhub/user.py +++ b/jupyterhub/user.py @@ -1,6 +1,6 @@ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. -import codecs +import json import warnings from collections import defaultdict from datetime import datetime @@ -352,9 +352,9 @@ class User: return quote(self.name, safe='@~') @property - def unicode_escaped_name(self): + def json_escaped_name(self): """My name, escaped for use in javascript inserts, etc.""" - return codecs.unicode_escape_encode(self.name)[0].decode() + return json.dumps(self.name)[1:-1] @property def proxy_spec(self): diff --git a/share/jupyterhub/templates/page.html b/share/jupyterhub/templates/page.html index c641c1c4..cd50ee11 100644 --- a/share/jupyterhub/templates/page.html +++ b/share/jupyterhub/templates/page.html @@ -63,7 +63,7 @@ base_url: "{{base_url}}", prefix: "{{prefix}}", {% if user %} - user: "{{user.unicode_escaped_name}}", + user: "{{user.json_escaped_name}}", {% endif %} {% if admin_access %} admin_access: true,