Skip to content

Commit fd3fc8e

Browse files
committed
Merge pull request #3254 from Joshua-Anderson/list-users
feat(controller): add users:list endpoint
2 parents f97a8d8 + ecc1acc commit fd3fc8e

11 files changed

Lines changed: 1296 additions & 4 deletions

File tree

client/deis.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
keys manage ssh keys used for `git push` deployments
2626
perms manage permissions for applications
2727
git manage git for applications
28+
users manage users
2829
2930
Shortcut commands, use ``deis shortcuts`` to see all::
3031
@@ -75,7 +76,7 @@
7576
__version__ = '1.6.0-dev'
7677

7778
# what version of the API is this client compatible with?
78-
__api_version__ = '1.2'
79+
__api_version__ = '1.3'
7980

8081

8182
locale.setlocale(locale.LC_ALL, '')
@@ -2224,6 +2225,35 @@ def shortcuts(self, args):
22242225
self._logger.info("{:<10} -> {}".format(shortcut, command))
22252226
self._logger.info('\nUse `deis help [command]` to learn more')
22262227

2228+
def users(self, args):
2229+
"""
2230+
Valid commands for users:
2231+
2232+
users:list list all registered users
2233+
2234+
Use `deis help [command]` to learn more.
2235+
"""
2236+
sys.argv[1] = 'users:list'
2237+
args = docopt(self.users_list.__doc__)
2238+
return self.users_list(args)
2239+
2240+
def users_list(self, args):
2241+
"""
2242+
Lists all registered users.
2243+
Requires admin privilages.
2244+
2245+
Usage: deis users:list
2246+
"""
2247+
response = self._dispatch('get', '/v1/users/')
2248+
if response.status_code == requests.codes.ok:
2249+
data = response.json()
2250+
self._logger.info('=== Users')
2251+
for item in data['results']:
2252+
self._logger.info('{username}'.format(**item))
2253+
else:
2254+
raise ResponseError(response)
2255+
2256+
22272257
SHORTCUTS = OrderedDict([
22282258
('create', 'apps:create'),
22292259
('destroy', 'apps:destroy'),

controller/api/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
The **api** Django app presents a RESTful web API for interacting with the **deis** system.
33
"""
44

5-
__version__ = '1.2.0'
5+
__version__ = '1.3.0'

controller/api/tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,4 @@ def run_tests(self, test_labels, extra_tests=None, **kwargs):
5959
from .test_perm import * # noqa
6060
from .test_release import * # noqa
6161
from .test_scheduler import * # noqa
62+
from .test_users import * # noqa

controller/api/tests/test_users.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
from __future__ import unicode_literals
3+
4+
from django.contrib.auth.models import User
5+
from django.test import TestCase
6+
from rest_framework.authtoken.models import Token
7+
8+
9+
class TestUsers(TestCase):
10+
""" Tests users endpoint"""
11+
12+
fixtures = ['tests.json']
13+
14+
def test_super_user_can_list(self):
15+
url = '/v1/users/'
16+
17+
user = User.objects.get(username='autotest')
18+
token = Token.objects.get(user=user)
19+
20+
response = self.client.get(url,
21+
HTTP_AUTHORIZATION='token {}'.format(token))
22+
23+
self.assertEqual(response.status_code, 200)
24+
self.assertEqual(len(response.data['results']), 2)
25+
self.assertEqual(response.data['results'][0]['username'], 'autotest')
26+
self.assertEqual(response.data['results'][1]['username'], 'autotest2')
27+
28+
def test_non_super_user_cannot_list(self):
29+
url = '/v1/users/'
30+
31+
user = User.objects.get(username='autotest2')
32+
token = Token.objects.get(user=user)
33+
34+
response = self.client.get(url,
35+
HTTP_AUTHORIZATION='token {}'.format(token))
36+
self.assertEqual(response.status_code, 403)

controller/api/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,4 +86,6 @@
8686
views.CertificateViewSet.as_view({'get': 'retrieve', 'delete': 'destroy'})),
8787
url(r'^certs/?',
8888
views.CertificateViewSet.as_view({'get': 'list', 'post': 'create'})),
89+
# list users
90+
url(r'^users/', views.UserView.as_view({'get': 'list'})),
8991
)

controller/api/views.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,3 +385,13 @@ def destroy(self, request, **kwargs):
385385
user.is_superuser = user.is_staff = False
386386
user.save(update_fields=['is_superuser', 'is_staff'])
387387
return Response(status=status.HTTP_204_NO_CONTENT)
388+
389+
390+
class UserView(BaseDeisViewSet):
391+
"""A Viewset for interacting with User objects."""
392+
model = User
393+
serializer_class = serializers.UserSerializer
394+
permission_classes = [permissions.IsAdmin]
395+
396+
def get_queryset(self):
397+
return self.model.objects.exclude(username='AnonymousUser')

docs/reference/api-v1.2.rst

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
:title: Controller API v1.2
22
:description: The v1.2 REST API for Deis' Controller
33

4-
.. _controller_api_v1:
5-
64
Controller API v1.2
75
===================
86

0 commit comments

Comments
 (0)