diff --git a/jupyterhub/apihandlers/users.py b/jupyterhub/apihandlers/users.py new file mode 100644 index 00000000..504f8e50 --- /dev/null +++ b/jupyterhub/apihandlers/users.py @@ -0,0 +1,29 @@ +"""Authorization handlers""" + +# Copyright (c) Jupyter Development Team. +# Distributed under the terms of the Modified BSD License. + +import json + +from ..handlers import BaseHandler +from .. import orm +from ..utils import admin_only + + +class UserListAPIHandler(BaseHandler): + @admin_only + def get(self): + users = list(self.db.query(orm.User)) + + data = [] + for user in users: + data.append({ + 'name': user.name, + 'server': user.server.base_url if user.server else None, + }) + + self.write(json.dumps(data)) + +default_handlers = [ + (r"/api/users", UserListAPIHandler), +] diff --git a/jupyterhub/tests/test_api.py b/jupyterhub/tests/test_api.py index 109301b0..4b829592 100644 --- a/jupyterhub/tests/test_api.py +++ b/jupyterhub/tests/test_api.py @@ -5,13 +5,31 @@ import requests from ..utils import url_path_join as ujoin from .. import orm +def add_user(db, **kwargs): + user = orm.User(**kwargs) + db.add(user) + db.commit() + return user + +def auth_header(db, name): + user = db.query(orm.User).filter(orm.User.name==name).first() + if user is None: + user = add_user(db, name=name) + if not user.api_tokens: + token = user.new_api_token() + db.add(token) + db.commit() + else: + token = user.api_tokens[0] + return {'Authorization': 'token %s' % token.token} def api_request(app, *api_path, **kwargs): """Make an API request""" base_url = app.hub.server.url - token = app.db.query(orm.APIToken).first() - kwargs.setdefault('headers', {}) - kwargs['headers'].setdefault('Authorization', 'token %s' % token.token) + headers = kwargs.setdefault('headers', {}) + + if 'Authorization' not in headers: + headers.update(auth_header(app.db, 'admin')) url = ujoin(base_url, 'api', *api_path) method = kwargs.pop('method', 'get') @@ -47,3 +65,22 @@ def test_auth_api(app): assert r.status_code == 403 +def test_get_users(app): + db = app.db + r = api_request(app, 'users') + assert r.status_code == 200 + assert sorted(r.json(), key=lambda d: d['name']) == [ + { + 'name': 'admin', + 'server': None, + }, + { + 'name': 'user', + 'server': None, + } + ] + + r = api_request(app, 'users', + headers=auth_header(db, 'user'), + ) + assert r.status_code == 403