diff --git a/apps/assets/migrations/0055_auto_20200811_1845.py b/apps/assets/migrations/0055_auto_20200811_1845.py new file mode 100644 index 000000000..739378c78 --- /dev/null +++ b/apps/assets/migrations/0055_auto_20200811_1845.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.13 on 2020-08-11 10:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('assets', '0054_auto_20200807_1032'), + ] + + operations = [ + migrations.AddField( + model_name='systemuser', + name='home', + field=models.CharField(blank=True, default='', max_length=4096, verbose_name='Home'), + ), + migrations.AddField( + model_name='systemuser', + name='system_groups', + field=models.CharField(blank=True, default='', max_length=4096, verbose_name='System groups'), + ), + ] diff --git a/apps/assets/models/user.py b/apps/assets/models/user.py index d787cf7e7..3fb862760 100644 --- a/apps/assets/models/user.py +++ b/apps/assets/models/user.py @@ -9,6 +9,7 @@ from django.utils.translation import ugettext_lazy as _ from django.core.validators import MinValueValidator, MaxValueValidator from common.utils import signer +from common.fields.model import JsonListCharField from .base import BaseUser from .asset import Asset @@ -121,6 +122,8 @@ class SystemUser(BaseUser): cmd_filters = models.ManyToManyField('CommandFilter', related_name='system_users', verbose_name=_("Command filter"), blank=True) sftp_root = models.CharField(default='tmp', max_length=128, verbose_name=_("SFTP Root")) token = models.TextField(default='', verbose_name=_('Token')) + home = models.CharField(max_length=4096, default='', verbose_name=_('Home'), blank=True) + system_groups = models.CharField(default='', max_length=4096, verbose_name=_('System groups'), blank=True) _prefer = 'system_user' def __str__(self): diff --git a/apps/assets/serializers/system_user.py b/apps/assets/serializers/system_user.py index 1f2a05867..0fcff5b1d 100644 --- a/apps/assets/serializers/system_user.py +++ b/apps/assets/serializers/system_user.py @@ -34,7 +34,8 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): 'priority', 'username_same_with_user', 'auto_push', 'cmd_filters', 'sudo', 'shell', 'comment', 'auto_generate_key', 'sftp_root', 'token', - 'assets_amount', 'date_created', 'created_by' + 'assets_amount', 'date_created', 'created_by', + 'home', 'system_groups' ] extra_kwargs = { 'password': {"write_only": True}, @@ -144,13 +145,14 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): class SystemUserListSerializer(SystemUserSerializer): + class Meta(SystemUserSerializer.Meta): fields = [ 'id', 'name', 'username', 'protocol', 'login_mode', 'login_mode_display', 'priority', "username_same_with_user", 'auto_push', 'sudo', 'shell', 'comment', - "assets_amount", + "assets_amount", 'home', 'system_groups', 'auto_generate_key', 'sftp_root', ] diff --git a/apps/assets/tasks/push_system_user.py b/apps/assets/tasks/push_system_user.py index eb3978178..d947be77d 100644 --- a/apps/assets/tasks/push_system_user.py +++ b/apps/assets/tasks/push_system_user.py @@ -3,9 +3,10 @@ from itertools import groupby from celery import shared_task from django.utils.translation import ugettext as _ +from django.db.models import Empty from common.utils import encrypt_password, get_logger -from orgs.utils import tmp_to_org, org_aware_func +from orgs.utils import org_aware_func from . import const from .utils import clean_ansible_task_hosts, group_asset_by_platform @@ -17,20 +18,42 @@ __all__ = [ ] +def _split_by_comma(raw: str): + try: + return [i.strip() for i in raw.split(',')] + except AttributeError: + return [] + + +def _dump_args(args: dict): + return ' '.join([f'{k}={v}' for k, v in args.items() if v is not Empty]) + + def get_push_unixlike_system_user_tasks(system_user, username=None): if username is None: username = system_user.username password = system_user.password public_key = system_user.public_key + groups = _split_by_comma(system_user.system_groups) + + if groups: + groups = '"%s"' % ','.join(groups) + + add_user_args = { + 'name': username, + 'shell': system_user.shell or Empty, + 'state': 'present', + 'home': system_user.home or Empty, + 'groups': groups or Empty + } + tasks = [ { 'name': 'Add user {}'.format(username), 'action': { 'module': 'user', - 'args': 'name={} shell={} state=present'.format( - username, system_user.shell or '/bin/bash', - ), + 'args': _dump_args(add_user_args), } }, { @@ -102,6 +125,11 @@ def get_push_windows_system_user_tasks(system_user, username=None): if username is None: username = system_user.username password = system_user.password + groups = {'Users', 'Remote Desktop Users'} + if system_user.system_groups: + groups.update(_split_by_comma(system_user.system_groups)) + groups = ','.join(groups) + tasks = [] if not password: return tasks @@ -116,9 +144,9 @@ def get_push_windows_system_user_tasks(system_user, username=None): 'update_password=always ' 'password_expired=no ' 'password_never_expires=yes ' - 'groups="Users,Remote Desktop Users" ' + 'groups="{}" ' 'groups_action=add ' - ''.format(username, username, password), + ''.format(username, username, password, groups), } } tasks.append(task)