diff --git a/apps/assets/forms.py b/apps/assets/forms.py index 9af1896ae..4b2040e5f 100644 --- a/apps/assets/forms.py +++ b/apps/assets/forms.py @@ -12,7 +12,7 @@ class AssetForm(forms.ModelForm): fields = [ "ip", "other_ip", "remote_card_ip", "hostname", "port", "groups", "username", "password", "idc", "mac_address", "brand", "cpu", "memory", "disk", "os", "cabinet_no", "cabinet_pos", - "number", "status", "type", "env", "sn", "is_active", "comment", "admin_user", "system_user" + "number", "status", "type", "env", "sn", "is_active", "comment", "admin_user", "system_users" ] widgets = { diff --git a/apps/assets/models.py b/apps/assets/models.py index 52c11fb8c..2d66992a3 100644 --- a/apps/assets/models.py +++ b/apps/assets/models.py @@ -194,6 +194,21 @@ class SystemUser(models.Model): def public_key(self, public_key_raw): self._public_key = encrypt(public_key_raw) + def get_assets_inherit_from_asset_groups(self): + assets = set() + asset_groups = self.asset_groups.all() + for asset_group in asset_groups: + for asset in asset_group.assets.all(): + setattr(asset, 'is_inherit_from_asset_groups', True) + setattr(asset, 'inherit_from_asset_groups', + getattr(asset, b'inherit_from_asset_groups', set()).add(asset_group)) + assets.add(asset) + return assets + + def get_assets(self): + assets = set(self.assets.all()) | self.get_assets_inherit_from_asset_groups() + return list(assets) + class Meta: db_table = 'system_user' @@ -266,8 +281,8 @@ class Asset(models.Model): password = models.CharField(max_length=256, null=True, blank=True, verbose_name=_("Admin password")) admin_user = models.ForeignKey(AdminUser, null=True, blank=True, related_name='assets', on_delete=models.SET_NULL, verbose_name=_("Admin user")) - system_user = models.ManyToManyField(SystemUser, blank=True, related_name='assets', verbose_name=_("System User")) - idc = models.ForeignKey(IDC, null=True, blank=True, related_name='assets', on_delete=models.SET_NULL, verbose_name=_('IDC')) + system_users = models.ManyToManyField(SystemUser, blank=True, related_name='assets', verbose_name=_("System User")) + idc = models.ForeignKey(IDC, null=True, related_name='assets', on_delete=models.SET_NULL, verbose_name=_('IDC')) mac_address = models.CharField(max_length=20, null=True, blank=True, verbose_name=_("Mac address")) brand = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('Brand')) cpu = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('CPU')) @@ -301,7 +316,7 @@ class Asset(models.Model): @classmethod def generate_fake(cls, count=100): - from random import seed + from random import seed, choice import forgery_py from django.db import IntegrityError @@ -309,10 +324,14 @@ class Asset(models.Model): for i in range(count): asset = cls(ip='%s.%s.%s.%s' % tuple([forgery_py.forgery.basic.text(length=3, digits=True) for i in range(0, 4)]), + admin_user=choice(AdminUser.objects.all()), + idc=choice(IDC.objects.all()), port=22, created_by='Fake') try: asset.save() + asset.system_users = [choice(SystemUser.objects.all()) for i in range(3)] + asset.groups = [choice(AssetGroup.objects.all()) for i in range(3)] logger.debug('Generate fake asset : %s' % asset.ip) except IntegrityError: print('Error continue') @@ -335,5 +354,5 @@ class Label(models.Model): def generate_fake(): - for cls in (Asset, AssetGroup, IDC): - cls.generate_fake() \ No newline at end of file + for cls in (AssetGroup, IDC, AdminUser, SystemUser, Asset): + cls.generate_fake() diff --git a/apps/assets/templates/assets/admin_user_detail.html b/apps/assets/templates/assets/admin_user_detail.html index 12a108f6c..b02cde2c0 100644 --- a/apps/assets/templates/assets/admin_user_detail.html +++ b/apps/assets/templates/assets/admin_user_detail.html @@ -15,9 +15,9 @@
@@ -33,10 +33,6 @@ @@ -73,7 +69,7 @@
diff --git a/apps/assets/templates/assets/system_user_asset.html b/apps/assets/templates/assets/system_user_asset.html index 9f30c724e..c3f22749b 100644 --- a/apps/assets/templates/assets/system_user_asset.html +++ b/apps/assets/templates/assets/system_user_asset.html @@ -19,10 +19,7 @@ {% trans 'Detail' %}
  • - {% trans 'Associate assets' %} -
  • -
  • - {% trans 'Associate asset groups' %} + {% trans 'Associate assets and asset groups' %}
  • @@ -30,7 +27,7 @@
    diff --git a/apps/assets/templates/assets/system_user_detail.html b/apps/assets/templates/assets/system_user_detail.html index 7ca599d8f..68b00a0e8 100644 --- a/apps/assets/templates/assets/system_user_detail.html +++ b/apps/assets/templates/assets/system_user_detail.html @@ -20,13 +20,9 @@
  • - {% trans 'Associate assets' %} + {% trans 'Associate assets and asset groups' %}
  • -
  • - - {% trans 'Associate asset groups' %} -
  • diff --git a/apps/assets/templates/assets/system_user_list.html b/apps/assets/templates/assets/system_user_list.html index ac8672347..2a9b04178 100644 --- a/apps/assets/templates/assets/system_user_list.html +++ b/apps/assets/templates/assets/system_user_list.html @@ -11,7 +11,7 @@ {% trans 'Username' %} {% trans 'Asset num' %} {% trans 'Asset group num' %} - {% trans 'Unavailable' %} + {% trans 'Unreachable' %} {% trans 'Comment' %} {% endblock %} @@ -26,7 +26,7 @@ {{ system_user.username }} - {{ system_user.assets.count }} + {{ system_user.get_assets|length }} {{ system_user.asset_groups.count }} {{ system_user.assets.count }} {{ system_user.comment|truncatewords:4 }} diff --git a/apps/assets/urls.py b/apps/assets/urls.py index 175c01afc..f5260f33a 100644 --- a/apps/assets/urls.py +++ b/apps/assets/urls.py @@ -48,7 +48,7 @@ urlpatterns = [ url(r'^system-user/(?P[0-9]+)/update', views.SystemUserUpdateView.as_view(), name='system-user-update'), url(r'^system-user/(?P[0-9]+)/delete$', views.SystemUserDeleteView.as_view(), name='system-user-delete'), url(r'^system-user/(?P[0-9]+)/asset$', views.SystemUserAssetView.as_view(), name='system-user-asset'), - url(r'^system-user/(?P[0-9]+)/asset-group$', views.SystemUserAssetGroupView.as_view(), - name='system-user-asset-group'), + # url(r'^system-user/(?P[0-9]+)/asset-group$', views.SystemUserAssetGroupView.as_view(), + # name='system-user-asset-group'), # url(r'^api/v1.0/', include(router.urls)), ] diff --git a/apps/assets/views.py b/apps/assets/views.py index bbef0164f..48503757d 100644 --- a/apps/assets/views.py +++ b/apps/assets/views.py @@ -368,14 +368,13 @@ class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateVi self.object.name, )) - return self.success_message + return success_message class SystemUserUpdateView(AdminUserRequiredMixin, UpdateView): model = SystemUser form_class = SystemUserForm template_name = 'assets/system_user_create_update.html' - success_message = _('Update system user %s successfully.') def get_context_data(self, **kwargs): context = { @@ -386,7 +385,7 @@ class SystemUserUpdateView(AdminUserRequiredMixin, UpdateView): return super(SystemUserUpdateView, self).get_context_data(**kwargs) def get_success_url(self): - success_url = reverse_lazy('assets:system-user-detail', pk=self.object.pk) + success_url = reverse_lazy('assets:system-user-detail', kwargs={'pk': self.object.pk}) return success_url @@ -419,39 +418,47 @@ class SystemUserAssetView(AdminUserRequiredMixin, SingleObjectMixin, ListView): self.object = self.get_object(queryset=SystemUser.objects.all()) return super(SystemUserAssetView, self).get(request, *args, **kwargs) + def get_asset_groups(self): + return self.object.asset_groups.all() + # Todo: queryset default order by connectivity, need ops support def get_queryset(self): - return self.object.assets.all() + return list(self.object.get_assets()) def get_context_data(self, **kwargs): + asset_groups = self.get_asset_groups() + assets = self.get_queryset() context = { 'app': 'assets', 'action': 'System user asset', - 'assets': self.get_queryset(), + 'assets_remain': [asset for asset in Asset.objects.all() if asset not in assets], + 'asset_groups': asset_groups, + 'asset_groups_remain': [asset_group for asset_group in AssetGroup.objects.all() + if asset_group not in asset_groups] } kwargs.update(context) return super(SystemUserAssetView, self).get_context_data(**kwargs) -class SystemUserAssetGroupView(AdminUserRequiredMixin, SingleObjectMixin, ListView): - paginate_by = settings.CONFIG.DISPLAY_PER_PAGE - template_name = 'assets/system_user_asset_group.html' - context_object_name = 'system_user' - - def get(self, request, *args, **kwargs): - self.object = self.get_object(queryset=SystemUser.objects.all()) - return super(SystemUserAssetGroupView, self).get(request, *args, **kwargs) - +# class SystemUserAssetGroupView(AdminUserRequiredMixin, SingleObjectMixin, ListView): +# paginate_by = settings.CONFIG.DISPLAY_PER_PAGE +# template_name = 'assets/system_user_asset_group.html' +# context_object_name = 'system_user' +# +# def get(self, request, *args, **kwargs): +# self.object = self.get_object(queryset=SystemUser.objects.all()) +# return super(SystemUserAssetGroupView, self).get(request, *args, **kwargs) +# # Todo: queryset default order by connectivity, need ops support - def get_queryset(self): - return self.object.asset_groups.all() - - def get_context_data(self, **kwargs): - context = { - 'app': 'assets', - 'action': 'System user asset group', - 'asset_groups': self.get_queryset(), - } - kwargs.update(context) - return super(SystemUserAssetGroupView, self).get_context_data(**kwargs) + # def get_queryset(self): + # return self.object.asset_groups.all() + # + # def get_context_data(self, **kwargs): + # context = { + # 'app': 'assets', + # 'action': 'System user asset group', + # 'asset_groups': self.get_queryset(), + # } + # kwargs.update(context) + # return super(SystemUserAssetGroupView, self).get_context_data(**kwargs) diff --git a/apps/common/templatetags/common_tags.py b/apps/common/templatetags/common_tags.py index ca928c1c0..22f5133be 100644 --- a/apps/common/templatetags/common_tags.py +++ b/apps/common/templatetags/common_tags.py @@ -32,4 +32,14 @@ def pagination_range(total_page, current_num=1, display=5): start = current_num - display/2 if current_num > display/2 else 1 end = start + display if start + display <= total_page else total_page + 1 - return range(start, end) \ No newline at end of file + return range(start, end) + + +@register.filter +def join_attr(seq, attr=None, sep=None): + if sep is None: + sep = ', ' + if attr is not None: + seq = [getattr(obj, attr) for obj in seq] + print(seq) + return sep.join(seq) diff --git a/apps/perms/forms.py b/apps/perms/forms.py index 1826b4c29..8638db75b 100644 --- a/apps/perms/forms.py +++ b/apps/perms/forms.py @@ -14,7 +14,7 @@ class AssetPermissionForm(forms.ModelForm): model = AssetPermission fields = [ 'name', 'users', 'user_groups', 'assets', 'asset_groups', - 'system_users', 'action', 'is_active', 'date_expired', 'comment', + 'system_users', 'is_active', 'date_expired', 'comment', ] widgets = { 'users': forms.SelectMultiple(attrs={'class': 'select2', diff --git a/apps/perms/models.py b/apps/perms/models.py index 60e150672..fd4189d87 100644 --- a/apps/perms/models.py +++ b/apps/perms/models.py @@ -11,18 +11,19 @@ from common.utils import date_expired_default, combine_seq class AssetPermission(models.Model): - ACTION_CHOICE = ( - ('1', 'Allow'), - ('0', 'Deny'), + PRIVATE_FOR_CHOICE = ( + ('N', 'None'), + ('U', 'user'), + ('G', 'user group'), ) - - name = models.CharField(max_length=128, verbose_name=_('Name')) + name = models.CharField(max_length=128, unique=True, verbose_name=_('Name')) users = models.ManyToManyField(User, related_name='asset_permissions', blank=True) user_groups = models.ManyToManyField(UserGroup, related_name='asset_permissions', blank=True) assets = models.ManyToManyField(Asset, related_name='granted_by_permissions', blank=True) asset_groups = models.ManyToManyField(AssetGroup, related_name='granted_by_permissions', blank=True) system_users = models.ManyToManyField(SystemUser, related_name='granted_by_permissions') - action = models.CharField(choices=ACTION_CHOICE, max_length=8, default='1') + private_for = models.CharField(choices=PRIVATE_FOR_CHOICE, max_length=1, default='N', blank=True, + verbose_name=_('Private for')) is_active = models.BooleanField(default=True, verbose_name=_('Active')) date_expired = models.DateTimeField(default=date_expired_default, verbose_name=_('Date expired')) created_by = models.CharField(max_length=128, blank=True, verbose_name=_('Created by')) @@ -30,7 +31,7 @@ class AssetPermission(models.Model): comment = models.TextField(verbose_name=_('Comment'), blank=True) def __unicode__(self): - return '%(name)s: %(action)s' % {'name': self.name, 'action': self.action} + return self.name @property def is_valid(self): @@ -38,32 +39,31 @@ class AssetPermission(models.Model): return True return True - @staticmethod - def set_inherit(obj): - setattr(obj, 'inherited', True) - return obj - def get_granted_users(self): - return list(set(self.users.all() or []) | set(self.get_granted_user_groups_member())) + return list(set(self.users.all()) | self.get_granted_user_groups_member()) def get_granted_user_groups_member(self): - combine_users = functools.partial(combine_seq, callback=AssetPermission.set_inherit) - try: - return functools.reduce(combine_users, [user_group.users.all() - for user_group in self.user_groups.iterator()]) - except TypeError: - return [] + users = set() + for user_group in self.user_groups.all(): + for user in user_group.users.all(): + setattr(user, 'is_inherit_from_user_groups', True) + setattr(user, 'inherit_from_user_groups', + getattr(user, b'inherit_from_user_groups', set()).add(user_group)) + users.add(user) + return users def get_granted_assets(self): - return list(set(self.assets.all() or []) | set(self.get_granted_asset_groups_member())) + return list(set(self.assets.all()) | self.get_granted_asset_groups_member()) def get_granted_asset_groups_member(self): - combine_assets = functools.partial(combine_seq, callback=AssetPermission.set_inherit) - try: - return functools.reduce(combine_assets, [asset_group.users.all() - for asset_group in self.asset_groups.iterator()]) - except TypeError: - return [] + assets = set() + for asset_group in self.asset_groups.all(): + for asset in asset_group.assets.all(): + setattr(asset, 'is_inherit_from_asset_groups', True) + setattr(asset, 'inherit_from_asset_groups', + getattr(asset, b'inherit_from_user_groups', set()).add(asset_group)) + assets.add(asset) + return assets class Meta: db_table = 'asset_permission' diff --git a/apps/perms/templates/perms/asset_permission_asset_list.html b/apps/perms/templates/perms/asset_permission_asset.html similarity index 97% rename from apps/perms/templates/perms/asset_permission_asset_list.html rename to apps/perms/templates/perms/asset_permission_asset.html index baad101d1..b6c0cfb00 100644 --- a/apps/perms/templates/perms/asset_permission_asset_list.html +++ b/apps/perms/templates/perms/asset_permission_asset.html @@ -26,7 +26,7 @@
  • - {% trans 'Assets and asset gruops' %} + {% trans 'Assets and asset groups' %}