Commit c9f4b104 authored by ibuler's avatar ibuler

Merge remote-tracking branch 'github/dev' into dev

parents 3bf1c036 ebecd005
...@@ -74,7 +74,7 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet): ...@@ -74,7 +74,7 @@ class AssetViewSet(IDInFilterMixin, LabelFilter, BulkModelViewSet):
.select_related('admin_user') .select_related('admin_user')
self.filter_admin_user_id() self.filter_admin_user_id()
self.filter_node() self.filter_node()
return self.queryset return self.queryset.distinct()
class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView): class AssetListUpdateApi(IDInFilterMixin, ListBulkCreateUpdateDestroyAPIView):
......
...@@ -26,7 +26,7 @@ class CommandFilterRuleViewSet(BulkModelViewSet): ...@@ -26,7 +26,7 @@ class CommandFilterRuleViewSet(BulkModelViewSet):
fpk = self.kwargs.get('filter_pk') fpk = self.kwargs.get('filter_pk')
if not fpk: if not fpk:
return CommandFilterRule.objects.none() return CommandFilterRule.objects.none()
group = get_object_or_404(CommandFilter, pk=fpk) cmd_filter = get_object_or_404(CommandFilter, pk=fpk)
return group.rules.all().order_by('priority') return cmd_filter.rules.all()
...@@ -150,7 +150,7 @@ class SystemUserForm(OrgModelForm, PasswordAndKeyAuthForm): ...@@ -150,7 +150,7 @@ class SystemUserForm(OrgModelForm, PasswordAndKeyAuthForm):
'name': '* required', 'name': '* required',
'username': '* required', 'username': '* required',
'auto_push': _('Auto push system user to asset'), 'auto_push': _('Auto push system user to asset'),
'priority': _('High level will be using login asset as default, ' 'priority': _('1-100, High level will be using login asset as default, '
'if user was granted more than 2 system user'), 'if user was granted more than 2 system user'),
'login_mode': _('If you choose manual login mode, you do not ' 'login_mode': _('If you choose manual login mode, you do not '
'need to fill in the username and password.') 'need to fill in the username and password.')
......
...@@ -44,7 +44,7 @@ class CommandFilterRule(OrgModelMixin): ...@@ -44,7 +44,7 @@ class CommandFilterRule(OrgModelMixin):
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
filter = models.ForeignKey('CommandFilter', on_delete=models.CASCADE, verbose_name=_("Filter"), related_name='rules') filter = models.ForeignKey('CommandFilter', on_delete=models.CASCADE, verbose_name=_("Filter"), related_name='rules')
type = models.CharField(max_length=16, default=TYPE_COMMAND, choices=TYPE_CHOICES, verbose_name=_("Type")) type = models.CharField(max_length=16, default=TYPE_COMMAND, choices=TYPE_CHOICES, verbose_name=_("Type"))
priority = models.IntegerField(default=50, verbose_name=_("Priority"), help_text=_("1-100, the lower will be match first"), priority = models.IntegerField(default=50, verbose_name=_("Priority"), help_text=_("1-100, the higher will be match first"),
validators=[MinValueValidator(1), MaxValueValidator(100)]) validators=[MinValueValidator(1), MaxValueValidator(100)])
content = models.TextField(max_length=1024, verbose_name=_("Content"), help_text=_("One line one command")) content = models.TextField(max_length=1024, verbose_name=_("Content"), help_text=_("One line one command"))
action = models.IntegerField(default=ACTION_DENY, choices=ACTION_CHOICES, verbose_name=_("Action")) action = models.IntegerField(default=ACTION_DENY, choices=ACTION_CHOICES, verbose_name=_("Action"))
...@@ -54,7 +54,7 @@ class CommandFilterRule(OrgModelMixin): ...@@ -54,7 +54,7 @@ class CommandFilterRule(OrgModelMixin):
created_by = models.CharField(max_length=128, blank=True, default='', verbose_name=_('Created by')) created_by = models.CharField(max_length=128, blank=True, default='', verbose_name=_('Created by'))
class Meta: class Meta:
ordering = ('priority', 'action') ordering = ('-priority', 'action')
def __str__(self): def __str__(self):
return '{} % {}'.format(self.type, self.content) return '{} % {}'.format(self.type, self.content)
...@@ -138,7 +138,7 @@ class Node(OrgModelMixin): ...@@ -138,7 +138,7 @@ class Node(OrgModelMixin):
args.append(Q(nodes__key__regex=pattern) | Q(nodes=None)) args.append(Q(nodes__key__regex=pattern) | Q(nodes=None))
else: else:
kwargs['nodes__key__regex'] = pattern kwargs['nodes__key__regex'] = pattern
assets = Asset.objects.filter(*args, **kwargs) assets = Asset.objects.filter(*args, **kwargs).distinct()
return assets return assets
def get_all_valid_assets(self): def get_all_valid_assets(self):
......
...@@ -7,6 +7,7 @@ import logging ...@@ -7,6 +7,7 @@ import logging
from django.core.cache import cache from django.core.cache import cache
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.validators import MinValueValidator, MaxValueValidator
from common.utils import get_signer from common.utils import get_signer
from ..const import SYSTEM_USER_CONN_CACHE_KEY from ..const import SYSTEM_USER_CONN_CACHE_KEY
...@@ -111,7 +112,8 @@ class SystemUser(AssetUser): ...@@ -111,7 +112,8 @@ class SystemUser(AssetUser):
nodes = models.ManyToManyField('assets.Node', blank=True, verbose_name=_("Nodes")) nodes = models.ManyToManyField('assets.Node', blank=True, verbose_name=_("Nodes"))
assets = models.ManyToManyField('assets.Asset', blank=True, verbose_name=_("Assets")) assets = models.ManyToManyField('assets.Asset', blank=True, verbose_name=_("Assets"))
priority = models.IntegerField(default=10, verbose_name=_("Priority")) priority = models.IntegerField(default=20, verbose_name=_("Priority"),
validators=[MinValueValidator(1), MaxValueValidator(100)])
protocol = models.CharField(max_length=16, choices=PROTOCOL_CHOICES, default='ssh', verbose_name=_('Protocol')) protocol = models.CharField(max_length=16, choices=PROTOCOL_CHOICES, default='ssh', verbose_name=_('Protocol'))
auto_push = models.BooleanField(default=True, verbose_name=_('Auto push')) auto_push = models.BooleanField(default=True, verbose_name=_('Auto push'))
sudo = models.TextField(default='/bin/whoami', verbose_name=_('Sudo')) sudo = models.TextField(default='/bin/whoami', verbose_name=_('Sudo'))
...@@ -168,7 +170,7 @@ class SystemUser(AssetUser): ...@@ -168,7 +170,7 @@ class SystemUser(AssetUser):
from .cmd_filter import CommandFilterRule from .cmd_filter import CommandFilterRule
rules = CommandFilterRule.objects.filter( rules = CommandFilterRule.objects.filter(
filter__in=self.cmd_filters.all() filter__in=self.cmd_filters.all()
).order_by('priority').distinct() ).distinct()
return rules return rules
@classmethod @classmethod
......
...@@ -69,6 +69,10 @@ ...@@ -69,6 +69,10 @@
<td>{% trans 'Port' %}:</td> <td>{% trans 'Port' %}:</td>
<td><b>{{ asset.port }}</b></td> <td><b>{{ asset.port }}</b></td>
</tr> </tr>
<tr>
<td>{% trans 'Protocol' %}:</td>
<td><b>{{ asset.protocol }}</b></td>
</tr>
<tr> <tr>
<td>{% trans 'Admin user' %}:</td> <td>{% trans 'Admin user' %}:</td>
<td><b>{{ asset.admin_user }}</b></td> <td><b>{{ asset.admin_user }}</b></td>
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<div class="alert alert-info help-message"> <div class="alert alert-info help-message">
{% trans 'System user bound some command filter, each command filter has some rules,'%} {% trans 'System user bound some command filter, each command filter has some rules,'%}
{% trans 'When user login asset with this system user, then run a command,' %} {% trans 'When user login asset with this system user, then run a command,' %}
{% trans 'The command will be filter by rules, higher priority(lower number) rule run first,' %} {% trans 'The command will be filter by rules, higher priority rule run first,' %}
{% trans 'When a rule matched, if rule action is allow, then allow command execute,' %} {% trans 'When a rule matched, if rule action is allow, then allow command execute,' %}
{% trans 'else if action is deny, then command with be deny,' %} {% trans 'else if action is deny, then command with be deny,' %}
{% trans 'else match next rule, if none matched, allowed' %} {% trans 'else match next rule, if none matched, allowed' %}
......
This diff is collapsed.
...@@ -96,7 +96,7 @@ class UserGrantedNodesApi(ListAPIView): ...@@ -96,7 +96,7 @@ class UserGrantedNodesApi(ListAPIView):
""" """
查询用户授权的所有节点的API, 如果是超级用户或者是 app,切换到root org 查询用户授权的所有节点的API, 如果是超级用户或者是 app,切换到root org
""" """
permission_classes = (IsOrgAdmin,) permission_classes = (IsOrgAdminOrAppUser,)
serializer_class = NodeSerializer serializer_class = NodeSerializer
def change_org_if_need(self): def change_org_if_need(self):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment