From 4e67749eef0a898571b68c460413e98a64140ed4 Mon Sep 17 00:00:00 2001 From: ibuler Date: Mon, 10 Jul 2017 10:26:17 +0800 Subject: [PATCH] =?UTF-8?q?[Docs]=20=E6=B7=BB=E5=8A=A0api=20dockers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/applications/api.py | 3 --- apps/assets/api.py | 1 + apps/assets/urls/api_urls.py | 10 +++---- apps/jumpserver/settings.py | 21 ++++++++++++++- apps/jumpserver/urls.py | 25 ++++++------------ apps/jumpserver/views.py | 10 +++---- apps/users/api.py | 32 +++++++++++++++++++++-- apps/users/templates/users/user_list.html | 2 -- apps/users/urls/api_urls.py | 9 ++++--- apps/users/views/user.py | 22 ++++++++-------- config_example.py | 15 +++++++++++ 11 files changed, 99 insertions(+), 51 deletions(-) diff --git a/apps/applications/api.py b/apps/applications/api.py index 75487bbba..3a58ed8e2 100644 --- a/apps/applications/api.py +++ b/apps/applications/api.py @@ -2,9 +2,6 @@ # from collections import OrderedDict -from django.core.cache import cache -from django.conf import settings -from django.utils import timezone import copy from rest_framework.generics import ListCreateAPIView from rest_framework import viewsets diff --git a/apps/assets/api.py b/apps/assets/api.py index 3f00e94f2..2647dbf78 100644 --- a/apps/assets/api.py +++ b/apps/assets/api.py @@ -191,6 +191,7 @@ class AssetAdminUserTestView(AssetRefreshHardwareView): class AssetGroupPushSystemUserView(generics.UpdateAPIView): queryset = AssetGroup.objects.all() permission_classes = (IsSuperUser,) + serializer_class = serializers.AssetSerializer def patch(self, request, *args, **kwargs): asset_group = self.get_object() diff --git a/apps/assets/urls/api_urls.py b/apps/assets/urls/api_urls.py index e6c213158..3a98f2157 100644 --- a/apps/assets/urls/api_urls.py +++ b/apps/assets/urls/api_urls.py @@ -8,14 +8,14 @@ app_name = 'assets' router = BulkRouter() -router.register(r'v1/asset-groups', api.AssetGroupViewSet, 'asset-group') +router.register(r'v1/groups', api.AssetGroupViewSet, 'asset-group') router.register(r'v1/assets', api.AssetViewSet, 'asset') router.register(r'v1/idc', api.IDCViewSet, 'idc') router.register(r'v1/admin-user', api.AdminUserViewSet, 'admin-user') router.register(r'v1/system-user', api.SystemUserViewSet, 'system-user') urlpatterns = [ - url(r'^v1/assets_bulk/$', api.AssetListUpdateApi.as_view(), name='asset-bulk-update'), + url(r'^v1/assets-bulk/$', api.AssetListUpdateApi.as_view(), name='asset-bulk-update'), url(r'^v1/system-user/(?P[0-9]+)/auth-info/', api.SystemUserAuthInfoApi.as_view(), name='system-user-auth-info'), url(r'^v1/assets/(?P\d+)/groups/$', @@ -29,14 +29,14 @@ urlpatterns = [ url(r'^v1/assets/(?P\d+)/system-users/$', api.SystemUserUpdateApi.as_view(), name='asset-update-system-users'), - url(r'^v1/asset-groups/(?P\d+)/push-system-user/$', + url(r'^v1/groups/(?P\d+)/push-system-user/$', api.AssetGroupPushSystemUserView.as_view(), name='asset-group-push-system-user'), # update the system users, which add and delete the asset to the system user - url(r'^v1/system_user/(?P\d+)/assets/$', + url(r'^v1/system-user/(?P\d+)/assets/$', api.SystemUserUpdateAssetsApi.as_view(), name='systemuser-update-assets'), - url(r'^v1/system_user/(?P\d+)/groups/$', + url(r'^v1/system-user/(?P\d+)/groups/$', api.SystemUserUpdateAssetGroupApi.as_view(), name='systemuser-update-assetgroups'), # update the asset group, which add or delete the asset to the group diff --git a/apps/jumpserver/settings.py b/apps/jumpserver/settings.py index 2012d2021..035052efc 100644 --- a/apps/jumpserver/settings.py +++ b/apps/jumpserver/settings.py @@ -59,6 +59,8 @@ INSTALLED_APPS = [ 'common.apps.CommonConfig', 'applications.apps.ApplicationsConfig', 'rest_framework', + 'rest_framework_swagger', + 'django_filters', 'bootstrap3', 'captcha', 'django.contrib.auth', @@ -289,12 +291,29 @@ REST_FRAMEWORK = { 'users.authentication.PrivateTokenAuthentication', 'users.authentication.SessionAuthentication', ), - # 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',), + 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',), } +AUTHENTICATION_BACKENDS = [ + 'django_auth_ldap.backend.LDAPBackend', + 'django.contrib.auth.backends.ModelBackend', +] + # Custom User Auth model AUTH_USER_MODEL = 'users.User' + +# Auth LDAP settings +if CONFIG.AUTH_LDAP: + AUTHENTICATION_BACKENDS.insert(0, 'django_auth_ldap.backend.LDAPBackend') +AUTH_LDAP_SERVER_URI = CONFIG.AUTH_LDAP_SERVER_URI +AUTH_LDAP_BIND_DN = CONFIG.AUTH_LDAP_BIND_DN +AUTH_LDAP_BIND_PASSWORD = CONFIG.AUTH_LDAP_BIND_PASSWORD +AUTH_LDAP_USER_DN_TEMPLATE = CONFIG.AUTH_LDAP_USER_DN_TEMPLATE +AUTH_LDAP_START_TLS = CONFIG.AUTH_LDAP_START_TLS +AUTH_LDAP_USER_ATTR_MAP = CONFIG.AUTH_LDAP_USER_ATTR_MAP + + # Celery using redis as broker BROKER_URL = 'redis://%(password)s%(host)s:%(port)s/3' % { 'password': CONFIG.REDIS_PASSWORD + ':' if CONFIG.REDIS_PASSWORD else '', diff --git a/apps/jumpserver/urls.py b/apps/jumpserver/urls.py index b9a878fa8..de74984a8 100644 --- a/apps/jumpserver/urls.py +++ b/apps/jumpserver/urls.py @@ -1,30 +1,17 @@ # ~*~ coding: utf-8 ~*~ from __future__ import unicode_literals -"""jumpserver URL Configuration - -The `urlpatterns` list routes URLs to views. For more information please see: - https://docs.djangoproject.com/en/1.10/topics/http/urls/ -Examples: -Function views - 1. Add an import: from my_app import views - 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') -Class-based views - 1. Add an import: from other_app.views import Home - 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') -Including another URLconf - 1. Import the include() function: from django.conf.urls import url, include - 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) -""" from django.conf.urls import url, include from django.conf import settings from django.conf.urls.static import static +from rest_framework.schemas import get_schema_view +from rest_framework_swagger.renderers import SwaggerUIRenderer, OpenAPIRenderer + from .views import IndexView - +schema_view = get_schema_view(title='Users API', renderer_classes=[OpenAPIRenderer, SwaggerUIRenderer]) urlpatterns = [ - url(r'^captcha/', include('captcha.urls')), url(r'^$', IndexView.as_view(), name='index'), url(r'^users/', include('users.urls.views_urls', namespace='users')), url(r'^assets/', include('assets.urls.views_urls', namespace='assets')), @@ -40,10 +27,14 @@ urlpatterns = [ url(r'^api/audits/', include('audits.urls.api_urls', namespace='api-audits')), url(r'^api/applications/', include('applications.urls.api_urls', namespace='api-applications')), url(r'^api/ops/', include('ops.urls.api_urls', namespace='api-ops')), + url(r'^captcha/', include('captcha.urls')), ] if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + urlpatterns += [ + url(r'^docs/', schema_view, name="docs"), + ] diff --git a/apps/jumpserver/views.py b/apps/jumpserver/views.py index 044d3fa8f..e08956de0 100644 --- a/apps/jumpserver/views.py +++ b/apps/jumpserver/views.py @@ -4,8 +4,6 @@ from django.db.models import Count from django.contrib.auth.mixins import LoginRequiredMixin from django.shortcuts import redirect - -from users.utils import AdminUserRequiredMixin from users.models import User from assets.models import Asset from audits.models import ProxyLog @@ -26,10 +24,10 @@ class IndexView(LoginRequiredMixin, TemplateView): proxy_log_month = ProxyLog.objects.filter(date_start__gt=month_ago, is_failed=False) month_dates = proxy_log_month.dates('date_start', 'day') month_total_visit = [ProxyLog.objects.filter(date_start__date=d) for d in month_dates] - month_str = [d.strftime('%m-%d') for d in month_dates] - month_total_visit_count = [p.count() for p in month_total_visit] - month_user = [p.values('user').distinct().count() for p in month_total_visit] - month_asset = [p.values('asset').distinct().count() for p in month_total_visit] + month_str = [d.strftime('%m-%d') for d in month_dates] or ['0'] + month_total_visit_count = [p.count() for p in month_total_visit] or [0] + month_user = [p.values('user').distinct().count() for p in month_total_visit] or [0] + month_asset = [p.values('asset').distinct().count() for p in month_total_visit] or [0] month_user_active = User.objects.filter(last_login__gt=month_ago).count() month_user_inactive = User.objects.filter(last_login__lt=month_ago).count() month_user_disabled = User.objects.filter(is_active=False).count() diff --git a/apps/users/api.py b/apps/users/api.py index 56f6d52c2..2258ace71 100644 --- a/apps/users/api.py +++ b/apps/users/api.py @@ -4,7 +4,9 @@ from rest_framework import generics from rest_framework.permissions import AllowAny from rest_framework.response import Response from rest_framework.views import APIView +from rest_framework import viewsets from rest_framework_bulk import BulkModelViewSet +from django_filters.rest_framework import DjangoFilterBackend from . import serializers from .hands import write_login_log_async @@ -18,11 +20,37 @@ from common.utils import get_logger logger = get_logger(__name__) -class UserViewSet(IDInFilterMixin, BulkModelViewSet): +# class UserListView(generics.ListAPIView): +# queryset = User.objects.all() +# serializer_class = serializers.UserSerializer +# filter_fields = ('username', 'email', 'name', 'id') + + +class UserViewSet(viewsets.ModelViewSet): + # class UserViewSet(IDInFilterMixin, BulkModelViewSet): + """ + retrieve: + Return a user instance . + + list: + Return all users except app user, ordered by most recently joined. + + create: + Create a new user. + + delete: + Remove an existing user. + + partial_update: + Update one or more fields on an existing user. + + update: + Update a user. + """ queryset = User.objects.all() + # queryset = User.objects.all().exclude(role="App").order_by("date_joined") serializer_class = serializers.UserSerializer permission_classes = (IsSuperUser,) - # filter_backends = (DjangoFilterBackend,) filter_fields = ('username', 'email', 'name', 'id') diff --git a/apps/users/templates/users/user_list.html b/apps/users/templates/users/user_list.html index 0cc5a8a80..51230c2d4 100644 --- a/apps/users/templates/users/user_list.html +++ b/apps/users/templates/users/user_list.html @@ -14,12 +14,10 @@ {% endblock %} {% block table_container %} -{##} diff --git a/apps/users/urls/api_urls.py b/apps/users/urls/api_urls.py index eaae47556..640e415d0 100644 --- a/apps/users/urls/api_urls.py +++ b/apps/users/urls/api_urls.py @@ -11,22 +11,23 @@ app_name = 'users' router = BulkRouter() router.register(r'v1/users', api.UserViewSet, 'user') -router.register(r'v1/user-groups', api.UserGroupViewSet, 'user-group') +router.register(r'v1/groups', api.UserGroupViewSet, 'user-group') urlpatterns = [ + # url(r'', api.UserListView.as_view()), url(r'^v1/token/$', api.UserToken.as_view(), name='user-token'), url(r'^v1/profile/$', api.UserProfile.as_view(), name='user-profile'), url(r'^v1/auth/$', api.UserAuthApi.as_view(), name='user-auth'), url(r'^v1/users/(?P\d+)/password/reset/$', api.UserResetPasswordApi.as_view(), name='user-reset-password'), - url(r'^v1/users/(?P\d+)/public-key/reset/$', + url(r'^v1/users/(?P\d+)/pubkey/reset/$', api.UserResetPKApi.as_view(), name='user-public-key-reset'), - url(r'^v1/users/(?P\d+)/public-key/update/$', + url(r'^v1/users/(?P\d+)/pubkey/update/$', api.UserUpdatePKApi.as_view(), name='user-public-key-update'), url(r'^v1/users/(?P\d+)/groups/$', api.UserUpdateGroupApi.as_view(), name='user-update-group'), - url(r'^v1/user-groups/(?P\d+)/users/$', + url(r'^v1/groups/(?P\d+)/users/$', api.UserGroupUpdateUserApi.as_view(), name='user-group-update-user'), ] diff --git a/apps/users/views/user.py b/apps/users/views/user.py index 9a7ab4d3c..e853c230e 100644 --- a/apps/users/views/user.py +++ b/apps/users/views/user.py @@ -20,8 +20,9 @@ from django.utils.decorators import method_decorator from django.views import View from django.views.generic import ListView from django.views.generic.base import TemplateView -from django.views.generic.edit import (CreateView, UpdateView, FormMixin, - FormView) +from django.views.generic.edit import ( + CreateView, UpdateView, FormMixin, FormView +) from django.views.generic.detail import DetailView, SingleObjectMixin from django.views.decorators.csrf import csrf_exempt from django.contrib.auth import logout as auth_logout @@ -33,13 +34,14 @@ from common.mixins import JSONResponseMixin from common.utils import get_logger, get_object_or_none from perms.models import AssetPermission -__all__ = ['UserListView', 'UserCreateView', 'UserDetailView', - 'UserUpdateView', 'UserAssetPermissionCreateView', - 'UserAssetPermissionView', 'UserGrantedAssetView', - 'UserExportView', 'UserBulkImportView', 'UserProfileView', - 'UserProfileUpdateView', 'UserPasswordUpdateView', - 'UserPublicKeyUpdateView', 'UserBulkUpdateView', - ] +__all__ = [ + 'UserListView', 'UserCreateView', 'UserDetailView', + 'UserUpdateView', 'UserAssetPermissionCreateView', + 'UserAssetPermissionView', 'UserGrantedAssetView', + 'UserExportView', 'UserBulkImportView', 'UserProfileView', + 'UserProfileUpdateView', 'UserPasswordUpdateView', + 'UserPublicKeyUpdateView', 'UserBulkUpdateView', +] logger = get_logger(__name__) @@ -52,8 +54,6 @@ class UserListView(AdminUserRequiredMixin, TemplateView): context.update({ 'app': _('Users'), 'action': _('User list'), - 'groups': UserGroup.objects.all(), - 'form': forms.UserBulkUpdateForm(), }) return context diff --git a/config_example.py b/config_example.py index aa3bd5883..fe63ac309 100644 --- a/config_example.py +++ b/config_example.py @@ -8,6 +8,8 @@ :license: GPL v2, see LICENSE for more details. """ import os +import ldap +from django_auth_ldap.config import LDAPSearch BASE_DIR = os.path.dirname(os.path.abspath(__file__)) LOG_DIR = os.path.join(BASE_DIR, 'logs') @@ -93,6 +95,19 @@ class Config: # You can set jumpserver usage url here, that when user submit wizard redirect to USER_GUIDE_URL = '' + # LDAP Auth settings + AUTH_LDAP = False + AUTH_LDAP_SERVER_URI = 'ldap://localhost:389' + AUTH_LDAP_BIND_DN = 'cn=admin,dc=jumpserver,dc=org' + AUTH_LDAP_BIND_PASSWORD = '' + AUTH_LDAP_USER_DN_TEMPLATE = "uid=%(user)s,ou=people,dc=jumpserver,dc=org" + AUTH_LDAP_USER_ATTR_MAP = { + "username": "cn", + "name": "sn", + "email": "mail" + } + AUTH_LDAP_START_TLS = False + def __init__(self): pass
-{#
#}
{% trans 'Name' %}