diff --git a/apps/jumpserver/urls.py b/apps/jumpserver/urls.py index e76b4f3a2..65de2eb4c 100644 --- a/apps/jumpserver/urls.py +++ b/apps/jumpserver/urls.py @@ -31,7 +31,7 @@ schema_view = get_schema_view( public=True, permission_classes=(permissions.AllowAny,), ) -api_url_pattern = re.compile(r'^/api/(?P\w+)/(?P\w+)/(?P.*)$') +api_url_pattern = re.compile(r'^/api/(?P\w+)/(?P\w+)/(?P.*)$') class HttpResponseTemporaryRedirect(HttpResponse): @@ -43,12 +43,12 @@ class HttpResponseTemporaryRedirect(HttpResponse): @csrf_exempt -def redirect_old_format_api(request, *args, **kwargs): +def redirect_format_api(request, *args, **kwargs): path, query = request.path, request.GET.urlencode() matched = api_url_pattern.match(path) if matched: - app, version, extra = matched.groups() - path = '/api/{version}/{app}/{extra}?{query}'.format(**{ + version, app, extra = matched.groups() + path = '/api/{app}/{version}/{extra}?{query}'.format(**{ "app": app, "version": version, "extra": extra, "query": query }) @@ -58,14 +58,14 @@ def redirect_old_format_api(request, *args, **kwargs): v1_api_patterns = [ - url(r'^users/', include('users.urls.api_urls', namespace='api-users')), - url(r'^assets/', include('assets.urls.api_urls', namespace='api-assets')), - url(r'^perms/', include('perms.urls.api_urls', namespace='api-perms')), - url(r'^terminal/', include('terminal.urls.api_urls', namespace='api-terminal')), - url(r'^ops/', include('ops.urls.api_urls', namespace='api-ops')), - url(r'^audits/', include('audits.urls.api_urls', namespace='api-audits')), - url(r'^orgs/', include('orgs.urls.api_urls', namespace='api-orgs')), - url(r'^common/', include('common.urls.api_urls', namespace='api-common')), + url(r'^users/v1/', include('users.urls.api_urls', namespace='api-users')), + url(r'^assets/v1/', include('assets.urls.api_urls', namespace='api-assets')), + url(r'^perms/v1/', include('perms.urls.api_urls', namespace='api-perms')), + url(r'^terminal/v1/', include('terminal.urls.api_urls', namespace='api-terminal')), + url(r'^ops/v1/', include('ops.urls.api_urls', namespace='api-ops')), + url(r'^audits/v1/', include('audits.urls.api_urls', namespace='api-audits')), + url(r'^orgs/v1/', include('orgs.urls.api_urls', namespace='api-orgs')), + url(r'^common/v1/', include('common.urls.api_urls', namespace='api-common')), ] app_view_patterns = [ @@ -84,17 +84,14 @@ urlpatterns = [ url(r'^luna/', LunaView.as_view(), name='luna-error'), url(r'^settings/', include('common.urls.view_urls', namespace='settings')), url(r'^common/', include('common.urls.view_urls', namespace='common')), - url(r'^api/v1/', include(v1_api_patterns)), - url(r'^api/(?P.*)/v1/.*', redirect_old_format_api), + url(r'^api/v1/.*', redirect_format_api), + url(r'^api/', include(v1_api_patterns)), # Api url view map # External apps url url(r'^captcha/', include('captcha.urls')), ] urlpatterns += app_view_patterns - -# urlpatterns = wrapper_patterns_with_org(urlpatterns) - urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) diff --git a/apps/jumpserver/views.py b/apps/jumpserver/views.py index 474eaf829..a924c5ef5 100644 --- a/apps/jumpserver/views.py +++ b/apps/jumpserver/views.py @@ -22,7 +22,7 @@ class IndexView(AdminUserRequiredMixin, TemplateView): session_month_dates_archive = [] def dispatch(self, request, *args, **kwargs): - if not request.user.is_org_admin: + if not request.user.is_authenticated or not request.user.is_org_admin: return redirect('assets:user-asset-list') return super(IndexView, self).dispatch(request, *args, **kwargs) diff --git a/apps/orgs/mixins.py b/apps/orgs/mixins.py index 244d967d0..4a47f2ee3 100644 --- a/apps/orgs/mixins.py +++ b/apps/orgs/mixins.py @@ -10,14 +10,15 @@ from django.forms import ModelForm from django.http.response import HttpResponseForbidden from common.utils import get_logger -from .utils import current_org, set_current_org +from .utils import current_org, set_current_org, set_to_root_org from .models import Organization logger = get_logger(__file__) tl = local() __all__ = [ - 'OrgManager', 'OrgViewGenericMixin', 'OrgModelMixin', 'OrgModelForm' + 'OrgManager', 'OrgViewGenericMixin', 'OrgModelMixin', 'OrgModelForm', + 'RootOrgViewMixin', ] @@ -85,6 +86,12 @@ class OrgViewGenericMixin: return super().dispatch(request, *args, **kwargs) +class RootOrgViewMixin: + def dispatch(self, request, *args, **kwargs): + set_to_root_org() + return super().dispatch(request, *args, **kwargs) + + class OrgModelForm(ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/apps/perms/api.py b/apps/perms/api.py index 042070f47..d8691a4c2 100644 --- a/apps/perms/api.py +++ b/apps/perms/api.py @@ -9,6 +9,7 @@ from rest_framework.pagination import LimitOffsetPagination from common.utils import set_or_append_attr_bulk, get_object_or_none from common.permissions import IsValidUser, IsOrgAdmin, IsOrgAdminOrAppUser +from orgs.mixins import RootOrgViewMixin from .utils import AssetPermissionUtil from .models import AssetPermission from .hands import AssetGrantedSerializer, User, UserGroup, Asset, Node, \ @@ -86,7 +87,7 @@ class UserGrantedAssetsApi(ListAPIView): return super().get_permissions() -class UserGrantedNodesApi(ListAPIView): +class UserGrantedNodesApi(RootOrgViewMixin, ListAPIView): permission_classes = (IsOrgAdmin,) serializer_class = NodeSerializer @@ -101,13 +102,12 @@ class UserGrantedNodesApi(ListAPIView): return nodes.keys() def get_permissions(self): - set_current_org(Organization.root()) if self.kwargs.get('pk') is None: self.permission_classes = (IsValidUser,) return super().get_permissions() -class UserGrantedNodesWithAssetsApi(ListAPIView): +class UserGrantedNodesWithAssetsApi(RootOrgViewMixin, ListAPIView): permission_classes = (IsOrgAdminOrAppUser,) serializer_class = NodeGrantedSerializer @@ -131,13 +131,12 @@ class UserGrantedNodesWithAssetsApi(ListAPIView): return queryset def get_permissions(self): - set_current_org(Organization.root()) if self.kwargs.get('pk') is None: self.permission_classes = (IsValidUser,) return super().get_permissions() -class UserGrantedNodeAssetsApi(ListAPIView): +class UserGrantedNodeAssetsApi(RootOrgViewMixin, ListAPIView): permission_classes = (IsOrgAdminOrAppUser,) serializer_class = AssetGrantedSerializer @@ -158,7 +157,6 @@ class UserGrantedNodeAssetsApi(ListAPIView): return assets def get_permissions(self): - set_current_org(Organization.root()) if self.kwargs.get('pk') is None: self.permission_classes = (IsValidUser,) return super().get_permissions() @@ -241,7 +239,7 @@ class UserGroupGrantedNodeAssetsApi(ListAPIView): return assets -class ValidateUserAssetPermissionView(APIView): +class ValidateUserAssetPermissionView(RootOrgViewMixin, APIView): permission_classes = (IsOrgAdminOrAppUser,) @staticmethod diff --git a/apps/perms/forms.py b/apps/perms/forms.py index 3ce3db6c5..d6383d927 100644 --- a/apps/perms/forms.py +++ b/apps/perms/forms.py @@ -29,8 +29,7 @@ class AssetPermissionForm(OrgModelForm): return users_field = self.fields.get('users') if hasattr(users_field, 'queryset'): - # users_field.queryset = User.objects.filter(orgs=current_org) - users_field.queryset = current_org.get_org_users().exclude(role=User.ROLE_APP) + users_field.queryset = current_org.get_org_users() class Meta: model = AssetPermission diff --git a/apps/perms/models.py b/apps/perms/models.py index 1c3a67d8e..89f09764e 100644 --- a/apps/perms/models.py +++ b/apps/perms/models.py @@ -25,7 +25,7 @@ class AssetPermissionManager(OrgManager): class AssetPermission(OrgModelMixin): id = models.UUIDField(default=uuid.uuid4, primary_key=True) - name = models.CharField(max_length=128, unique=True, verbose_name=_('Name')) + name = models.CharField(max_length=128, verbose_name=_('Name')) users = models.ManyToManyField('users.User', related_name='asset_permissions', blank=True, verbose_name=_("User")) user_groups = models.ManyToManyField('users.UserGroup', related_name='asset_permissions', blank=True, verbose_name=_("User group")) assets = models.ManyToManyField('assets.Asset', related_name='granted_by_permissions', blank=True, verbose_name=_("Asset")) @@ -40,6 +40,9 @@ class AssetPermission(OrgModelMixin): objects = AssetPermissionManager.from_queryset(AssetPermissionQuerySet)() + class Meta: + unique_together = [('org_id', 'name')] + def __str__(self): return self.name diff --git a/apps/perms/templates/perms/asset_permission_list.html b/apps/perms/templates/perms/asset_permission_list.html index 013447901..36504ef59 100644 --- a/apps/perms/templates/perms/asset_permission_list.html +++ b/apps/perms/templates/perms/asset_permission_list.html @@ -250,12 +250,10 @@ function initTree() { value["iconSkin"] = value["is_node"] ? null : 'file'; }); zNodes = data; - {#$.fn.zTree.init($("#assetTree"), setting);#} $.fn.zTree.init($("#assetTree"), setting, zNodes); zTree = $.fn.zTree.getZTreeObj("assetTree"); var root = zTree.getNodes()[0]; zTree.expandNode(root); - {#selectQueryNode();#} }); } diff --git a/apps/perms/views.py b/apps/perms/views.py index 411405848..7782992d5 100644 --- a/apps/perms/views.py +++ b/apps/perms/views.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals, absolute_import from django.utils.translation import ugettext as _ -from django.views.generic import ListView, CreateView, UpdateView, DetailView +from django.views.generic import ListView, CreateView, UpdateView, DetailView, TemplateView from django.views.generic.edit import DeleteView, SingleObjectMixin from django.urls import reverse_lazy from django.conf import settings @@ -15,11 +15,8 @@ from .models import AssetPermission from .forms import AssetPermissionForm -class AssetPermissionListView(AdminUserRequiredMixin, ListView): - model = AssetPermission +class AssetPermissionListView(AdminUserRequiredMixin, TemplateView): template_name = 'perms/asset_permission_list.html' - paginate_by = settings.DISPLAY_PER_PAGE - user = user_group = asset = node = system_user = q = "" def get_context_data(self, **kwargs): context = {