diff --git a/pym/unix/unix.py b/pym/unix/unix.py index 75b4a2e..95e30e7 100644 --- a/pym/unix/unix.py +++ b/pym/unix/unix.py @@ -103,7 +103,7 @@ class UnixGroups(object): yield UnixGroup( group['cn'][0], int(group['gidNumber'][0]), - group.get('memberUid', []), + sorted(group.get('memberUid', [])), group['description'][0]) def search_ldap_group(self, search_filter): @@ -554,7 +554,7 @@ class Unix(Ldap): login=user, groups=", ".join(groups))) return True - def modify_user(self, login, pw, gid, shell, visible, lock, comment): + def modify_user(self, login, pw, pw_delete, gid, shell, visible, lock, comment): """" Изменить параметры пользователя в LDAP """ @@ -572,10 +572,14 @@ class Unix(Ldap): params['comment'] = comment self.printSUCCESS( _("Changed comment for user %s") % user.username) - if pw: + if pw != UnixUsers.DeletedPassword or pw_delete: params['pw'] = pw - self.printSUCCESS( - _("Changed password for user %s") % user.username) + if pw_delete: + self.printSUCCESS( + _("Removed password for user %s") % user.username) + else: + self.printSUCCESS( + _("Changed password for user %s") % user.username) if shell and user.shell != shell: params['shell'] = shell self.printSUCCESS( @@ -636,9 +640,10 @@ class Unix(Ldap): raise UnixError(_("Failed to create user home directory")) return True - def show_groups(self, fields, count, offset): + def show_groups(self, groupname, fields, count, offset): dv = self.clVars + fields = ["ur_unix_group_name"] + list(fields) head = [dv.getInfo(x).label for x in fields] body = [] ldap_connect = self.clVars.Get('ldap.cl_ldap_connect') @@ -652,12 +657,12 @@ class Unix(Ldap): for x in ('cl_unix_group_filter_name', 'cl_unix_group_filter_id', 'cl_unix_group_filter_comment', - 'cl_unix_group_filter_users', - 'cl_unix_group_filter_primary')) + 'cl_unix_group_filter_users')) filters = [x.test for x in filters if x.enabled()] def all_users(group): - for user in uu.iterate_ldap_user("gidNumber=%d" % group.gid): + for user in sorted(uu.iterate_ldap_user("gidNumber=%d" % group.gid), + key=lambda x: x.username): yield "<%s>" % user.username for user in group.user_list: yield user @@ -669,29 +674,47 @@ class Unix(Ldap): 'ur_unix_group_users': lambda group: ", ".join(all_users(group)) } - for group in ug.iterate_ldap_group("cn=*", offset, count): - if all(x(group) for x in filters): - body.append([variables_mapping.get(x)(group) for x in fields]) - mapping = {'ur_unix_group_name': 'ur_unix_group_name_exists'} + + maxi = 0 + + try: + for i, group in enumerate(sorted( + (group for group in + ug.iterate_ldap_group("cn=*") + if all(x(group) for x in filters)), + key=lambda x: x.group_name)): + maxi = i + if offset <= i < offset + count: + body.append( + [variables_mapping.get(x)(group) for x in fields]) + except LDAPBadSearchFilter: + raise UnixError(_("Wrong group pattern")) + table_fields = [mapping.get(x, '') for x in fields] if not body: body = [[]] dv.Invalidate('ur_unix_group_count') + + if any(body): + head_message = _("Groups") + elif dv.GetInteger("ur_unix_group_count"): + head_message = _("Groups not found") + else: + head_message = _("No groups") self.printTable( - _("Groups") if any(body) else _("No groups"), head, body, - fields=table_fields, - onClick='unix_groupmod' if any(table_fields) else None, - addAction='unix_groupadd', - records=self.clVars.Get('core.cl_page_max')) + head_message, head, body, + fields=table_fields, + onClick='unix_groupmod' if any(table_fields) else None, + addAction='unix_groupadd', + records=str(maxi)) if any(body): num_page, count_page = getPagesInterval( - count, offset, int(self.clVars.Get('core.cl_page_max'))) + count, offset, maxi) self.printSUCCESS(_('page %d from ') % num_page + str(count_page)) return True def show_group(self, groupname): - print groupname dv = self.clVars list_group_name = sorted(dv.Choice('cl_core_group')) @@ -718,12 +741,16 @@ class Unix(Ldap): body.append([varobj.label or "", varval]) if body: - self.printTable(_("Group info"), head, body) + self.printTable(_("Group info"), head, body, + onClick="unix_groupmod", + records="0", + fields=["ur_unix_group_name_exists:%s" % groupname]) return True def show_users(self, login, fields, count, offset): dv = self.clVars + fields = ["ur_unix_login"] + list(fields) head = [dv.getInfo(x).label for x in fields] body = [] ldap_connect = self.clVars.Get('ldap.cl_ldap_connect') @@ -765,11 +792,17 @@ class Unix(Ldap): } mapping = {'ur_unix_login': 'ur_unix_login_exists'} + maxi = 0 try: - for user in uu.iterate_ldap_user("uid=%s" % login, offset, count): - if all(x(user) for x in filters): + for i, user in enumerate(sorted( + (user for user in uu.iterate_ldap_user("uid=*") + if all(x(user) for x in filters)), + key=lambda x: x.username)): + maxi = i + if offset <= i < offset + count: body.append( [variables_mapping.get(x)(user) for x in fields]) + except LDAPBadSearchFilter: raise UnixError(_("Wrong user pattern")) table_fields = [mapping.get(x, '') for x in fields] @@ -777,15 +810,21 @@ class Unix(Ldap): if not body: body = [[]] dv.Invalidate('ur_unix_user_count') - self.printTable(_("Users") if any(body) else _("No Users"), + if any(body): + head_message = _("Users") + elif dv.GetInteger("ur_unix_user_count"): + head_message = _("Users not found") + else: + head_message = _("No users") + self.printTable(head_message, head, body, fields=table_fields, onClick='unix_usermod' if any(table_fields) else None, addAction='unix_useradd', - records=str(self.clVars.Get('unix.ur_unix_user_count'))) + records=str(maxi)) if any(body): num_page, count_page = getPagesInterval( - count, offset, int(self.clVars.Get('unix.ur_unix_user_count'))) + count, offset, maxi) self.printSUCCESS(_('page %d from ') % num_page + str(count_page)) return True @@ -818,7 +857,10 @@ class Unix(Ldap): body.append([varobj.label or "", varval]) if body: - self.printTable(_("User info"), head, body) + self.printTable(_("User info"), head, body, + onClick="unix_usermod", + records="0", + fields=["ur_unix_login_exists:%s" % user]) return True def try_remove_primary_group(self, user, primary_group): diff --git a/pym/unix/utils/cl_unix_groupdel.py b/pym/unix/utils/cl_unix_groupdel.py index c4cd127..c9f317c 100644 --- a/pym/unix/utils/cl_unix_groupdel.py +++ b/pym/unix/utils/cl_unix_groupdel.py @@ -56,10 +56,6 @@ class ClUnixGroupdelAction(Action): # список задач для действия tasks = [ - {'name': 'remove_group_users', - 'message': _("Users {unix.ur_unix_group_users} removed " - "from group {unix.ur_unix_group_name}"), - }, {'name': 'remove_group', 'method': 'Unix.remove_group(unix.ur_unix_group_name)' }, diff --git a/pym/unix/utils/cl_unix_groupshow.py b/pym/unix/utils/cl_unix_groupshow.py index b2473b5..168de35 100644 --- a/pym/unix/utils/cl_unix_groupshow.py +++ b/pym/unix/utils/cl_unix_groupshow.py @@ -53,12 +53,13 @@ class ClUnixGroupshowAction(Action): # список задач для действия tasks = [ {'name': 'view_groups', - 'method': 'Unix.show_groups(unix.cl_unix_group_show_fields,' + 'method': 'Unix.show_groups(unix.ur_unix_group_show,' + 'unix.cl_unix_group_show_fields,' 'core.cl_page_count,core.cl_page_offset)', - 'condition': lambda Get: Get('ur_unix_group_show') == "all" + 'condition': lambda Get: not Get('ur_unix_group_show') }, {'name': 'view_group', 'method': 'Unix.show_group(ur_unix_group_show)', - 'condition': lambda Get: Get('ur_unix_group_show') != "all" + 'condition': lambda Get: Get('ur_unix_group_show') } ] diff --git a/pym/unix/utils/cl_unix_passwd.py b/pym/unix/utils/cl_unix_passwd.py index 19f556a..a688cfd 100644 --- a/pym/unix/utils/cl_unix_passwd.py +++ b/pym/unix/utils/cl_unix_passwd.py @@ -57,6 +57,7 @@ class ClUnixPasswdAction(Action): tasks = [ {'name': 'user_change', 'method': 'Unix.modify_user(ur_unix_login,ur_unix_hash,' + 'ur_unix_pw_delete_set,' 'None,None,None,ur_unix_lock_set, None)' }, ] diff --git a/pym/unix/utils/cl_unix_setup.py b/pym/unix/utils/cl_unix_setup.py index 72895c5..bcd4174 100644 --- a/pym/unix/utils/cl_unix_setup.py +++ b/pym/unix/utils/cl_unix_setup.py @@ -82,6 +82,9 @@ class ClUnixSetupAction(Action): 'tasks': meta_tasks.ldif_task("ldap.ld_admin_dn,ldap.ld_admin_pw", Actions.Setup) }, + {'name': 'set_unix', + 'method': 'Server.service_install("unix")' + }, {'name': 'templates', 'message': __("Configure LDAP"), 'method': 'Server.applyTemplates(install.cl_source,' @@ -90,9 +93,6 @@ class ClUnixSetupAction(Action): {'name': 'save_creds', 'method': 'Server.save_service_data("unix",ld_unix_dn,ld_unix_pw)' }, - {'name': 'set_unix', - 'method': 'Server.service_install("unix")' - }, {'name': 'restart_slapd', 'message': __("Restarting LDAP service"), 'method': 'Server.restart_service("%s")' % Ldap.Service.LDAP, diff --git a/pym/unix/utils/cl_unix_userdel.py b/pym/unix/utils/cl_unix_userdel.py index 7ba448f..3632ce1 100644 --- a/pym/unix/utils/cl_unix_userdel.py +++ b/pym/unix/utils/cl_unix_userdel.py @@ -57,8 +57,6 @@ class ClUnixUserdelAction(Action): # список задач для действия tasks = [ {'name': 'remove_group_users', - 'message': _("User {unix.ur_unix_login} removed " - "from groups {unix.ur_unix_groups}"), 'method': 'Unix.remove_user_from_groups(unix.ur_unix_login,' 'unix.ur_unix_groups)', 'condition': lambda Get: Get('unix.ur_unix_groups') diff --git a/pym/unix/utils/cl_unix_usermod.py b/pym/unix/utils/cl_unix_usermod.py index c058ec3..1e0faf6 100644 --- a/pym/unix/utils/cl_unix_usermod.py +++ b/pym/unix/utils/cl_unix_usermod.py @@ -56,7 +56,8 @@ class ClUnixUsermodAction(Action): # список задач для действия tasks = [ {'name': 'user_change', - 'method': 'Unix.modify_user(ur_unix_login,ur_unix_pw,ur_unix_gid,' + 'method': 'Unix.modify_user(ur_unix_login,ur_unix_hash,' + 'ur_unix_pw_delete_set,ur_unix_gid,' 'ur_unix_shell,ur_unix_visible_set,ur_unix_lock_set,' 'ur_unix_comment)', }, diff --git a/pym/unix/utils/cl_unix_usershow.py b/pym/unix/utils/cl_unix_usershow.py index 2c249da..f786fbd 100644 --- a/pym/unix/utils/cl_unix_usershow.py +++ b/pym/unix/utils/cl_unix_usershow.py @@ -56,10 +56,10 @@ class ClUnixUsershowAction(Action): 'method': 'Unix.show_users(unix.ur_unix_user_show,' 'unix.cl_unix_user_show_fields,' 'core.cl_page_count,core.cl_page_offset)', - 'condition': lambda Get: "*" in Get('ur_unix_user_show') + 'condition': lambda Get: not Get('ur_unix_user_show') }, {'name': 'view_user', 'method': 'Unix.show_user(ur_unix_user_show)', - 'condition': lambda Get: "*" not in Get('ur_unix_user_show') + 'condition': lambda Get: Get('ur_unix_user_show') } ] diff --git a/pym/unix/variables/action.py b/pym/unix/variables/action.py index 5e62043..7c0e793 100644 --- a/pym/unix/variables/action.py +++ b/pym/unix/variables/action.py @@ -34,7 +34,6 @@ class VariableClUnixAction(UnixGroupHelper, UnixUserHelper, Variable): if (value not in Actions.All and not self.GetBool('server.sr_unix_set')): raise VariableError(_("Unix service is not setup")) - # TODO: возможно отлавливать ошибку LDAP if value in Actions.UserExists and not self.ldap_user_list(): raise VariableError(_("Unix service has not users")) if value in Actions.GroupExists and not self.ldap_group_list(): diff --git a/pym/unix/variables/filters.py b/pym/unix/variables/filters.py index 2ea9e52..d191704 100644 --- a/pym/unix/variables/filters.py +++ b/pym/unix/variables/filters.py @@ -18,8 +18,11 @@ import sys import re from fnmatch import fnmatch from calculate.lib.datavars import (Variable, VariableInterface, VariableError) -from calculate.unix.variables.helpers import (UnixUserHelper, UnixGroupHelper) +from calculate.unix.variables.helpers import (UnixUserHelper, UnixGroupHelper, + UnixActionHelper) +from calculate.lib.cl_ldap import LDAPConnectError import operator +from itertools import chain _ = lambda x: x from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate) @@ -173,7 +176,6 @@ class VariableClUnixUserFilterLogin(FilterStringHelper, Variable): """ Фильтр на login """ - opt = ["--filter-login"] def init(self): self.label = _("Login filter") @@ -269,8 +271,8 @@ class VariableClUnixUserFilterUid(FilterIntegerHelper, Variable): opt = ["--filter-uid"] def init(self): - self.label = _("Uid filter") - self.help = _("set uid filter") + self.label = _("User ID filter") + self.help = _("set user ID filter") def test(self, user): return self.test_value(user.uid) @@ -360,33 +362,19 @@ class VariableClUnixGroupFilterComment(FilterStringHelper, Variable): return self.test_value(group.comment) -class VariableClUnixGroupFilterUsers(FilterListHelper, Variable): +class VariableClUnixGroupFilterUsers(FilterListHelper, UnixUserHelper, + Variable): """ Фильтр на наличие пользователей в группе """ opt = ["--filter-users"] - def init(self): - self.label = _("Users filter") - self.help = _("set users filter") - - def test(self, group): - return self.test_value(group.user_list) - - -class VariableClUnixGroupFilterPrimary(FilterListHelper, UnixUserHelper, - Variable): - """ - Фильтр на наличие пользователей в primary-group - """ - opt = ["--filter-primary"] - def init(self): self.label = _("Users filter") self.help = _("set users filter") def test(self, group): return self.test_value( - user.username for user in self.iterate_ldap_user( - "gidNumber=%d" % group.gid) - ) + chain(group.user_list, + (user.username for user in self.iterate_ldap_user( + "gidNumber=%d" % group.gid)))) diff --git a/pym/unix/variables/groups.py b/pym/unix/variables/groups.py index 96177ee..d444c2a 100644 --- a/pym/unix/variables/groups.py +++ b/pym/unix/variables/groups.py @@ -408,32 +408,12 @@ class VariableUrUnixGroupNewname(UnixGroupHelper, Variable): return value -class VariableUrUnixGroupShow(UnixGroupHelper, UnixActionHelper, Variable): - """ - Группа - """ - type = "choice" - opt = ["-G", "--group"] - metavalue = "GROUP" - - def init(self): - self.label = _("Group name") - self.help = _("show group") - - def get(self): - return "all" - - def choice_exists(self): - return ([("all", _("All"))] - + self.ldap_group_list()) - - class VariableClUnixGroupAliases(ReadonlyVariable): """ Алиасы для переменных """ type = "table" - value = [('name', 'ur_unix_group_name'), + value = [#('name', 'ur_unix_group_name'), ('id', 'ur_unix_group_id'), ('comment', 'ur_unix_group_comment'), ('users', 'ur_unix_group_users')] @@ -469,3 +449,28 @@ class VariableClUnixGroupShowFields(ReadonlyVariable): def get(self): mapping = dict(self.Get('cl_unix_group_aliases')) return [mapping[x] for x in self.Get('cl_unix_group_fields')] + + +class VariableUrUnixGroupShow(UnixGroupHelper, + UnixActionHelper, Variable): + """ + Фильтр на group name + """ + type = "choiceedit" + opt = ["ur_unix_group_show"] + metavalue = "GROUP" + value = "" + + def init(self): + self.label = _("Group name") + self.help = _("show group") + + def choice_exists(self): + return [("","")] + self.ldap_group_list() + + def check_exists(self, value): + if value: + if not self.search_ldap_group_name(value): + raise VariableError(_("%s group not found") % value) + + diff --git a/pym/unix/variables/unix.py b/pym/unix/variables/unix.py index 4df2232..329da04 100644 --- a/pym/unix/variables/unix.py +++ b/pym/unix/variables/unix.py @@ -76,10 +76,33 @@ class VariableLdUnixPw(ServerEnvHelper, RandomPasswordHelper, Variable): """ password_len = 9 service = "unix" - parameter = "pass" + parameter = "PASS" @property def fallback_value(self): return "test22" - return RandomPasswordHelper.get(self) + def get(self): + if self.Get('ld_unix_pw_generate_set') == 'on': + return "test22" + return RandomPasswordHelper.get(self) + else: + super(VariableLdUnixPw, self).get() + +class VariableLdUnixPwGenerateSet(Variable): + """ + Перегенерировать пароль или нет + """ + type = "bool" + + opt = ("-g", "--gen-password") + + def init(self): + self.label = _("Generate new service password") + self.help = _("generate new service password") + + def get(self): + if self.Get('server.sr_unix_set') == 'on': + return "off" + else: + return "on" diff --git a/pym/unix/variables/users.py b/pym/unix/variables/users.py index d0b7654..64c3f82 100644 --- a/pym/unix/variables/users.py +++ b/pym/unix/variables/users.py @@ -124,6 +124,7 @@ class VariableUrUnixComment(ExistsUserHelper, UnixActionHelper, Variable): return "" # self._value_formatter.format(self.value_format, self.Get) + class VariableUrUnixHomePath(ExistsUserHelper, UnixActionHelper, Variable): """ Путь до домашней директории @@ -247,7 +248,6 @@ class VariableUrUnixGid(UnixGroupHelper, ReadonlyVariable): return self.Get('ur_unix_next_gid') - class VariableUrUnixUid(UnixUserHelper, UnixActionHelper, Variable): """ UID пользователя @@ -459,6 +459,7 @@ class VariableUrUnixPw(Variable): value = "" untrusted = True metavalue = "PASSWORD" + check_after = ["ur_unix_pw_delete_set", 'ur_unix_lock_set'] def init(self): self.label = _("Password") @@ -468,9 +469,14 @@ class VariableUrUnixPw(Variable): delete_pw = self.GetBool('ur_unix_pw_delete_set') change_lock = (self.GetBool('ur_unix_lock_set') != self.GetBool('ur_unix_lock_exists_set')) + print delete_pw, change_lock, self.GetBool('ur_unix_lock_set') if (self.Get('cl_unix_action') == Actions.Passwd and not delete_pw and not change_lock and not value): raise PasswordError(_("Specify user password")) + if self.Get('cl_unix_action') in (Actions.Passwd, Actions.UserMod): + if self.Get('ur_unix_pw_delete_set') == 'on' and value: + raise VariableError(_("Can not use remove and " + "set the password options together")) class VariableUrUnixPwSet(UnixActionHelper, UnixUserHelper, ReadonlyVariable): @@ -498,7 +504,7 @@ class VariableUrUnixPwDeleteSet(Variable): type = "bool" value = "off" - opt = ("-d", "--delete") + opt = ("--delete-password",) def init(self): self.label = _("Remove user password") @@ -622,36 +628,6 @@ class VariableUrUnixMinUid(Variable): value = "10000" -class VariableUrUnixUserShow(UnixUserHelper, UnixActionHelper, Variable): - """ - Группа - """ - type = "choiceedit" - opt = ["-U", "--user"] - metavalue = "USER" - - def init(self): - self.label = _("login") - self.help = _("show user (support regular expressions)") - - def get(self): - return "*" - - def choice_exists(self): - try: - return ([("*", _("*"))] - + self.ldap_user_list()) - except LDAPConnectError as s: - raise VariableError(str(s)) - - def check_new(self, value): - if not value: - raise VariableError(_("Please specify user")) - if "*" not in value: - if not self.search_ldap_user_name(value): - raise VariableError(_("%s user not found") % value) - - class VariableUrUnixUserCount(UnixUserHelper, UnixActionHelper, ReadonlyVariable): """ @@ -669,7 +645,7 @@ class VariableClUnixUserAliases(ReadonlyVariable): """ type = "table" value = [ - ('login', 'ur_unix_login'), + # ('login', 'ur_unix_login'), ('uid', 'ur_unix_uid'), ('gid', 'ur_unix_primary_group'), ('comment', 'ur_unix_comment'), @@ -707,3 +683,30 @@ class VariableClUnixCreateGroupSet(UnixGroupHelper, ReadonlyVariable): if self.search_ldap_group("cn={0}".format(group_name)): return "off" return "on" + + +class VariableUrUnixUserShow(UnixUserHelper, UnixActionHelper, Variable): + """ + Фильтр на login + """ + type = "choiceedit" + opt = ["ur_unix_user_show"] + metavalue = "USER" + + def init(self): + self.label = _("Login") + self.help = _("show user") + + def get(self): + return "" + + def choice_exists(self): + try: + return [("", "")] + self.ldap_user_list() + except LDAPConnectError as s: + raise VariableError(str(s)) + + def check_exists(self, value): + if value: + if not self.search_ldap_user_name(value): + raise VariableError(_("%s user not found") % value) diff --git a/pym/unix/wsdl_unix.py b/pym/unix/wsdl_unix.py index 7622ed6..746ce83 100644 --- a/pym/unix/wsdl_unix.py +++ b/pym/unix/wsdl_unix.py @@ -88,8 +88,16 @@ class Wsdl(WsdlBase): 'server.sr_ldap_set', 'server.sr_unix_set', ), + expert=('ld_unix_pw_generate_set', + 'cl_verbose_set',), hide=(), - expert=(), + custom_buttons=[ + ('but0', _("Remove"), + Unix.Method.Setup, + "button", None, + lambda Get: Get('server.sr_unix_set') == 'on'), + ('but1', None, _("Next"), "button_next"), + ] ), ], 'depends': [Ldap.Method.Setup], @@ -518,7 +526,7 @@ class Wsdl(WsdlBase): # идентификатор метода 'method_name': Unix.Method.GroupShow, # категория метода - 'category': __('Server'), + 'category': __('Server Accounts'), # заголовок метода 'title': __("Unix Groups"), # иконка для графической консоли @@ -559,12 +567,11 @@ class Wsdl(WsdlBase): 'core.cl_page_count', 'core.cl_page_offset', ), expert=( - 'cl_unix_group_fields', 'cl_unix_group_filter_name', 'cl_unix_group_filter_id', 'cl_unix_group_filter_comment', 'cl_unix_group_filter_users', - 'cl_unix_group_filter_primary', + 'cl_unix_group_fields', ), custom_buttons=[ ('but0', _("Add Group"), @@ -585,7 +592,7 @@ class Wsdl(WsdlBase): # идентификатор метода 'method_name': Unix.Method.UserShow, # категория метода - 'category': __('Server'), + 'category': __('Server Accounts'), # заголовок метода 'title': __("Unix Users"), # иконка для графической консоли @@ -626,7 +633,6 @@ class Wsdl(WsdlBase): 'core.cl_page_count', 'core.cl_page_offset', ), expert=( - 'cl_unix_user_fields', 'cl_unix_user_filter_login', 'cl_unix_user_filter_pw_set', 'cl_unix_user_filter_comment', @@ -637,6 +643,7 @@ class Wsdl(WsdlBase): 'cl_unix_user_filter_shell', 'cl_unix_user_filter_visible_set', 'cl_unix_user_filter_lock_set', + 'cl_unix_user_fields', ), custom_buttons=[ ('but0', _("Add User"),