Merge pull request #728 from w-toguchi83/feature/add_admin_api

Add admin api
pull/729/head
Piero Toffanin 2019-09-13 16:56:31 -04:00 zatwierdzone przez GitHub
commit afda52f902
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
4 zmienionych plików z 248 dodań i 3 usunięć

Wyświetl plik

@ -14,8 +14,8 @@ RUN apt-get -qq install -y nodejs
# Configure use of testing branch of Debian
RUN printf "Package: *\nPin: release a=stable\nPin-Priority: 900\n" > /etc/apt/preferences.d/stable.pref
RUN printf "Package: *\nPin: release a=testing\nPin-Priority: 750\n" > /etc/apt/preferences.d/testing.pref
RUN printf "deb http://mirror.steadfast.net/debian/ stable main contrib non-free\ndeb-src http://mirror.steadfast.net/debian/ stable main contrib non-free" > /etc/apt/sources.list.d/stable.list
RUN printf "deb http://mirror.steadfast.net/debian/ testing main contrib non-free\ndeb-src http://mirror.steadfast.net/debian/ testing main contrib non-free" > /etc/apt/sources.list.d/testing.list
RUN printf "deb http://ftp.us.debian.org/debian/ stable main contrib non-free\ndeb-src http://ftp.us.debian.org/debian/ stable main contrib non-free" > /etc/apt/sources.list.d/stable.list
RUN printf "deb http://ftp.us.debian.org/debian/ testing main contrib non-free\ndeb-src http://ftp.us.debian.org/debian/ testing main contrib non-free" > /etc/apt/sources.list.d/testing.list
# Install Node.js GDAL, nginx, letsencrypt, psql
RUN apt-get -qq update && apt-get -qq install -t testing -y binutils libproj-dev gdal-bin nginx grass-core certbot && apt-get -qq install -y gettext-base cron postgresql-client-9.6

37
app/api/admin.py 100644
Wyświetl plik

@ -0,0 +1,37 @@
from django.contrib.auth.models import User, Group
from rest_framework import serializers, viewsets, generics
from rest_framework.permissions import IsAdminUser
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
class UserViewSet(viewsets.ModelViewSet):
serializer_class = UserSerializer
permission_classes = [IsAdminUser]
def get_queryset(self):
queryset = User.objects.all()
email = self.request.query_params.get('email', None)
if email is not None:
queryset = queryset.filter(email=email)
return queryset
class GroupSerializer(serializers.ModelSerializer):
class Meta:
model = Group
fields = '__all__'
class GroupViewSet(viewsets.ModelViewSet):
serializer_class = GroupSerializer
permission_classes = [IsAdminUser]
def get_queryset(self):
queryset = Group.objects.all()
name = self.request.query_params.get('name', None)
if name is not None:
queryset = queryset.filter(name=name)
return queryset

Wyświetl plik

@ -5,6 +5,7 @@ from app.plugins import get_api_url_patterns
from .projects import ProjectViewSet
from .tasks import TaskViewSet, TaskTiles, TaskTilesJson, TaskDownloads, TaskAssets, TaskAssetsImport
from .processingnodes import ProcessingNodeViewSet, ProcessingNodeOptionsView
from .admin import UserViewSet, GroupViewSet
from rest_framework_nested import routers
from rest_framework_jwt.views import obtain_jwt_token
@ -17,11 +18,16 @@ router.register(r'presets', PresetViewSet, base_name='presets')
tasks_router = routers.NestedSimpleRouter(router, r'projects', lookup='project')
tasks_router.register(r'tasks', TaskViewSet, base_name='projects-tasks')
admin_router = routers.DefaultRouter()
admin_router.register(r'admin/users', UserViewSet, basename='user')
admin_router.register(r'admin/groups', GroupViewSet, basename='group')
urlpatterns = [
url(r'processingnodes/options/$', ProcessingNodeOptionsView.as_view()),
url(r'^', include(router.urls)),
url(r'^', include(tasks_router.urls)),
url(r'^', include(admin_router.urls)),
url(r'projects/(?P<project_pk>[^/.]+)/tasks/(?P<pk>[^/.]+)/(?P<tile_type>orthophoto|dsm|dtm)/tiles/(?P<z>[\d]+)/(?P<x>[\d]+)/(?P<y>[\d]+)\.png$', TaskTiles.as_view()),
url(r'projects/(?P<project_pk>[^/.]+)/tasks/(?P<pk>[^/.]+)/(?P<tile_type>orthophoto|dsm|dtm)/tiles\.json$', TaskTilesJson.as_view()),
@ -33,4 +39,4 @@ urlpatterns = [
url(r'^token-auth/', obtain_jwt_token),
]
urlpatterns += get_api_url_patterns()
urlpatterns += get_api_url_patterns()

Wyświetl plik

@ -0,0 +1,202 @@
from django.contrib.auth.models import User, Group
from rest_framework import status
from rest_framework.test import APIClient
from rest_framework_jwt.settings import api_settings
from .classes import BootTestCase
from app.api.admin import UserSerializer, GroupSerializer
class TestApi(BootTestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test_user(self):
##
## Super user operation
##
client = APIClient()
super_user_name = 'testsuperuser'
super_user_pass = 'test1234'
# Get token
res = client.post('/api/token-auth/', {
'username': super_user_name,
'password': super_user_pass,
})
self.assertEqual(res.status_code, status.HTTP_200_OK)
super_user_token = res.data['token']
client = APIClient(HTTP_AUTHORIZATION="{0} {1}".format(api_settings.JWT_AUTH_HEADER_PREFIX, super_user_token))
# Can create (active) user
res = client.post('/api/admin/users/', {'username': 'testuser999', 'email': 'testuser999@test.com', 'password': 'test999', 'is_active': True})
self.assertEqual(res.status_code, status.HTTP_201_CREATED)
user = User.objects.get(username='testuser999')
self.assertTrue(user != None)
self.assertFalse(user.is_superuser)
self.assertTrue(user.is_active)
# Can get user
created_user_id = user.id
res = client.get('/api/admin/users/{}/'.format(created_user_id))
self.assertEqual(res.status_code, status.HTTP_200_OK)
self.assertEqual(res.data['username'], user.username)
self.assertEqual(res.data['email'], user.email)
self.assertEqual(res.data['password'], user.password)
# Can update user
res = client.put('/api/admin/users/{}/'.format(created_user_id), {'username': 'testuser888', 'email': 'testuser888@test.com', 'password': 'test888'})
self.assertEqual(res.status_code, status.HTTP_200_OK)
user = User.objects.filter(id=created_user_id).first()
self.assertTrue(user != None and (not user.is_superuser))
res = client.get('/api/admin/users/{}/'.format(created_user_id)) # ReGet user
self.assertEqual(res.data['username'], user.username)
self.assertEqual(res.data['email'], user.email)
self.assertEqual(res.data['password'], user.password)
# Can find user by email
res = client.get('/api/admin/users/?email=testuser888@test.com')
self.assertEqual(res.status_code, status.HTTP_200_OK)
self.assertEqual(res.data['count'], 1)
result = res.data['results'][0]
self.assertEqual(result['id'], user.id)
self.assertEqual(result['username'], user.username)
self.assertEqual(result['email'], 'testuser888@test.com')
# Can delete user
res = client.delete('/api/admin/users/{}/'.format(created_user_id))
self.assertEqual(res.status_code, status.HTTP_204_NO_CONTENT)
user = User.objects.filter(id=created_user_id).first()
self.assertTrue(user is None)
##
## user operation
##
client = APIClient()
user_name = 'testuser'
user_pass = 'test1234'
# Get token
res = client.post('/api/token-auth/', {
'username': user_name,
'password': user_pass,
})
self.assertEqual(res.status_code, status.HTTP_200_OK)
user_token = res.data['token']
client = APIClient(HTTP_AUTHORIZATION="{0} {1}".format(api_settings.JWT_AUTH_HEADER_PREFIX, user_token))
# Can't create user
res = client.post('/api/admin/users/', {'username': 'testuser999', 'email': 'testuser999@test.com', 'password': 'test999', 'is_active': True})
self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
user = User.objects.filter(username='testuser999').first()
self.assertTrue(user is None)
user = User.objects.get(username=user_name)
# Can't get user
res = client.get('/api/admin/users/{}/'.format(user.id))
self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
# Can't update user
res = client.put('/api/admin/users/{}/'.format(user.id), {'password': 'changed'})
self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
# Can't delete user
res = client.delete('/api/admin/users/{}/'.format(user.id))
self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
def test_group(self):
##
## Super user operaiton
##
client = APIClient()
super_user_name = 'testsuperuser'
super_user_pass = 'test1234'
# Get token
res = client.post('/api/token-auth/', {
'username': super_user_name,
'password': super_user_pass,
})
self.assertEqual(res.status_code, status.HTTP_200_OK)
super_user_token = res.data['token']
client = APIClient(HTTP_AUTHORIZATION="{0} {1}".format(api_settings.JWT_AUTH_HEADER_PREFIX, super_user_token))
# Can create group
res = client.post('/api/admin/groups/', {'name': 'Test', 'permissions': [53, 54]})
self.assertEqual(res.status_code, status.HTTP_201_CREATED)
group = Group.objects.get(name='Test')
self.assertTrue(group != None)
serializer = GroupSerializer(group)
self.assertEqual([53, 54], serializer.data['permissions'])
# Can get group
created_group_id = group.id
res = client.get('/api/admin/groups/{}/'.format(created_group_id))
self.assertEqual(res.status_code, status.HTTP_200_OK)
self.assertEqual(res.data['name'], group.name)
# Can update group
res = client.put('/api/admin/groups/{}/'.format(created_group_id), {'name': 'TestTest', 'permissions': [37, 38]})
self.assertEqual(res.status_code, status.HTTP_200_OK)
group = Group.objects.filter(id=created_group_id).first()
self.assertTrue(group != None)
serializer = GroupSerializer(group)
res = client.get('/api/admin/groups/{}/'.format(created_group_id)) # ReGet group
self.assertEqual('TestTest', serializer.data['name'])
self.assertEqual([37, 38], serializer.data['permissions'])
# Can find group by name
res = client.get('/api/admin/groups/?name=TestTest')
self.assertEqual(res.status_code, status.HTTP_200_OK)
self.assertEqual(res.data['count'], 1)
result = res.data['results'][0]
self.assertEqual(result['id'], group.id)
self.assertEqual(result['name'], 'TestTest')
# Can delete group
res = client.delete('/api/admin/groups/{}/'.format(created_group_id))
self.assertTrue(res.status_code == status.HTTP_204_NO_CONTENT)
group = Group.objects.filter(id=created_group_id).first()
self.assertTrue(group is None)
##
## user operation
##
client = APIClient()
user_name = 'testuser'
user_pass = 'test1234'
# Get token
res = client.post('/api/token-auth/', {
'username': user_name,
'password': user_pass,
})
self.assertEqual(res.status_code, status.HTTP_200_OK)
user_token = res.data['token']
client = APIClient(HTTP_AUTHORIZATION="{0} {1}".format(api_settings.JWT_AUTH_HEADER_PREFIX, user_token))
# Can't create group
res = client.post('/api/admin/groups/', {'name': 'Test', 'permissions': [53, 54]})
self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
group = Group.objects.filter(name='Test').first()
self.assertTrue(group is None)
group = Group.objects.get(name='Default')
# Can't get group
res = client.get('/api/admin/groups/{}/'.format(group.id))
self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
# Can't update group
res = client.put('/api/admin/groups/{}/'.format(group.id), {'name': 'TestTest', 'permissions': [37, 38]})
self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
# Can't delete group
res = client.delete('/api/admin/groups/{}/'.format(group.id))
self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)