diff --git a/pym/unix/unix.py b/pym/unix/unix.py index 2ba1140..d7fc36c 100644 --- a/pym/unix/unix.py +++ b/pym/unix/unix.py @@ -13,33 +13,770 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +from collections import namedtuple import sys +from calculate.lib.utils.files import readLinesFile, listDirectory +from calculate.ldap.ldap import Ldap +from calculate.lib.utils.common import getPagesInterval import os from os import path -from calculate.core.server.func import MethodsInterface -from calculate.server.server import Server -from calculate.lib.utils.files import listDirectory -from calculate.ldap.ldap import Ldap import shutil _ = lambda x: x from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate) +from calculate.lib.cl_ldap import ldap, LDAPConnectError setLocalTranslate('cl_unix3', sys.modules[__name__]) __ = getLazyLocalTranslate(_) + class UnixError(Exception): pass + +UnixGroup = namedtuple("UnixGroup", ['group_name', 'gid', 'user_list', + 'comment']) + + +class GroupFile(object): + def __init__(self, group_fn='/etc/group'): + self.group_fn = group_fn + + def __iter__(self): + for line in (x for x in readLinesFile(self.group_fn) + if not x.startswith("#")): + data = line.strip().split(':')[:4] + if len(data) >= 4 and data[2].isdigit(): + yield UnixGroup(data[0], int(data[2]), + filter(None, data[3].split(",")), + "/etc/group") + + +class UnixGroups(object): + """ + Набор методов для нахождения параметров группы и сопаставления GID, + названия + """ + + groups = GroupFile() + + exception = UnixError + + ldap_connect = None + groups_dn = "" + + def __init__(self, ldap_connect, groups_dn): + self.ldap_connect = ldap_connect + self.groups_dn = groups_dn + + def search_system_group_name(self, name): + for group in (x for x in self.groups if x.group_name == name): + return group + else: + return None + + def search_system_group_id(self, gid): + for group in (x for x in self.groups if x.gid == gid): + return group + else: + return None + + def iterate_ldap_group(self, search_filter, offset=None, count=None): + ldap_connect = self.ldap_connect + if ldap_connect: + base_dn = self.groups_dn + if offset is not None: + below = lambda x: x < offset + else: + below = lambda x: False + if count is not None: + above = lambda x: x >= offset + count + else: + above = lambda x: False + for i, group in enumerate(x[0][1] for x in ldap_connect.ldap_search( + base_dn, ldap.SCOPE_ONELEVEL, search_filter)): + if below(i): + continue + if above(i): + break + yield UnixGroup( + group['cn'][0], + int(group['gidNumber'][0]), + group.get('memberUid', []), + group['description'][0]) + + def search_ldap_group(self, search_filter): + for group in self.iterate_ldap_group(search_filter): + return group + return None + + def search_ldap_group_name(self, value): + return self.search_ldap_group("cn=%s" % value) + + def gid_to_name(self, value): + if value.isdigit(): + value = int(value) + group = (self.search_ldap_group("gidNumber=%d" % value) or + self.search_system_group_id(value)) + if group: + return group.group_name + return value + + def ldap_group_list(self): + groups = list(x for x in self.iterate_ldap_group("cn=*")) + return [(x.group_name, "%s (%s)" % (x.group_name, x.comment)) + for x in sorted(groups, key=lambda k: k.gid)] + + def ldap_group_names(self): + return list(x.group_name for x in self.iterate_ldap_group("cn=*")) + + def check_group(self, value): + ldap_group = self.search_ldap_group_name(value) + unix_group = ldap_group or self.search_system_group_name(value) + if not unix_group: + raise self.exception(_("Group %s not found") % value) + if not ldap_group and unix_group: + raise self.exception( + _("You should create group %s (%d) in Unix service") % + (unix_group.group_name, unix_group.gid)) + + def group_dn(self, group): + return "cn=%s,%s" % (group, self.groups_dn) + + def add_users_to_group(self, users, group): + try: + self.ldap_connect.ldap_modify_attrs( + self.group_dn(group), + ((ldap.MOD_ADD, 'memberUid', user) for user in users)) + except LDAPConnectError as e: + raise UnixError(_("Failed to modify group in LDAP: %s") % str(e)) + + def update_group_id(self, group, gid): + try: + self.ldap_connect.ldap_modify_attrs( + self.group_dn(group), + [(ldap.MOD_REPLACE, 'gidNumber', gid)]) + except LDAPConnectError as e: + raise UnixError(_("Failed to update group id in LDAP: %s") % str(e)) + + def update_group_comment(self, group, comment): + try: + self.ldap_connect.ldap_modify_attrs( + self.group_dn(group), + [(ldap.MOD_REPLACE, 'description', comment)]) + except LDAPConnectError as e: + raise UnixError( + _("Failed to update group comment in LDAP: %s") % str(e)) + + def remove_users_from_group(self, users, group): + try: + self.ldap_connect.ldap_modify_attrs( + self.group_dn(group), + ((ldap.MOD_DELETE, 'memberUid', user) for user in users)) + except LDAPConnectError as e: + raise UnixError( + _("Failed to remove users from group in LDAP: %s") % str(e)) + + def rename_group(self, oldname, newname): + try: + old_dn = self.group_dn(oldname) + new_dn = "cn=%s" % newname + self.ldap_connect.ldap_modify_dn(old_dn, new_dn) + except LDAPConnectError as e: + raise UnixError( + _("Failed to rename the group in LDAP: %s") % str(e)) + + def remove_group(self, group): + try: + self.ldap_connect.ldap_remove_dn(self.group_dn(group)) + except LDAPConnectError as e: + raise UnixError( + _("Failed to remove the group in LDAP: %s") % str(e)) + + +UnixUser = namedtuple( + "UnixUser", ['username', 'uid', 'gid', 'comment', 'homedir', 'shell', + 'visible', 'lock']) + + +class PasswdFile(object): + def __init__(self, passwd_fn='/etc/passwd'): + self.passwd_fn = passwd_fn + + def __iter__(self): + for line in (x for x in readLinesFile(self.passwd_fn) + if not x.startswith("#")): + data = line.strip().split(':')[:7] + if len(data) >= 7 and data[2].isdigit() and data[3].isdigit(): + yield UnixUser(data[0], int(data[2]), + int(data[3]), data[4], data[5], data[6], True, + False) + + +class UnixUsers(object): + """ + Набор методов для нахождения параметров пользователя и сопаставления UID, + названия + """ + passwd = PasswdFile() + + exception = UnixError + + ldap_connect = None + users_dn = "" + + DeletedPassword = "crypt{xxx}" + + def __init__(self, ldap_connect, users_dn): + self.ldap_connect = ldap_connect + self.users_dn = users_dn + + def search_system_user_name(self, name): + for user in (x for x in self.passwd if x.username == name): + return user + else: + return None + + def search_system_user_id(self, uid): + uid = int(uid) + for user in (x for x in self.passwd if x.uid == uid): + return user + else: + return None + + def iterate_ldap_user(self, search_filter, offset=None, count=None): + ldap_connect = self.ldap_connect + if ldap_connect: + base_dn = self.users_dn + if offset is not None: + below = lambda x: x < offset + else: + below = lambda x: False + if count is not None: + above = lambda x: x >= offset + count + else: + above = lambda x: False + for i, user in enumerate(x[0][1] for x in ldap_connect.ldap_search( + base_dn, ldap.SCOPE_ONELEVEL, search_filter)): + if below(i): + continue + if above(i): + break + yield UnixUser( + user['uid'][0], + int(user['uidNumber'][0]), + int(user['gidNumber'][0]), + user['cn'][0], + user['homeDirectory'][0], + user['loginShell'][0], + self.flag_to_visible(user['shadowFlag'][0]), + self.flag_to_lock(user['shadowExpire'][0]), + ) + + def search_ldap_user(self, search_filter): + for user in self.iterate_ldap_user(search_filter): + return user + return None + + def search_ldap_user_name(self, value): + return self.search_ldap_user("uid=%s" % value) + + def search_ldap_user_id(self, value): + return self.search_ldap_user("uidNumber=%s" % value) + + def get_primary_gids(self): + ldap_connect = self.ldap_connect + if ldap_connect: + base_dn = self.users_dn + return list(ldap_connect.ldap_simple_search( + base_dn, "uid=*", "gidNumber")) + return [] + + def get_password_hash(self, username): + ldap_connect = self.ldap_connect + if ldap_connect: + base_dn = self.users_dn + for pw in ldap_connect.ldap_simple_search( + self.users_dn, "uid=%s" % username, "userPassword"): + return pw + return "" + + def uid_to_name(self, value): + if value.isdigit(): + value = int(value) + user = (self.search_ldap_user("uidNumber=%d" % value) or + self.search_system_user_id(value)) + if user: + return user.username + return value + + def ldap_user_list(self): + users = list(x for x in self.iterate_ldap_user("uid=*")) + return [(x.username, "%s (%s)" % (x.username, x.comment)) + for x in sorted(users, key=lambda y: y.uid)] + + def ldap_user_names(self): + return list(x.username for x in self.iterate_ldap_user("uid=*")) + + # def check_user(self, value): + # ldap_user = self.search_ldap_user_name(value) + # unix_user = ldap_user or self.search_system_user_name(value) + # if not unix_user: + # raise VariableError(_("User %s not found") % value) + # if not ldap_user and unix_user: + # raise VariableError( + # _("You should create group %s (%d) in Unix service") % + # (unix_group.group_name, unix_group.gid)) + + def user_dn(self, user): + return "uid=%s,%s" % (user, self.users_dn) + + def update_user_group_id(self, user, gid): + try: + self.ldap_connect.ldap_modify_attrs( + self.user_dn(user), + [(ldap.MOD_REPLACE, 'gidNumber', gid)]) + except LDAPConnectError as e: + raise UnixError( + _("Failed to modify user primary group in LDAP: %s") % str(e)) + + def visible_to_flag(self, visible): + return "1" if visible else "0" + + def flag_to_visible(self, flag): + return flag == "1" + + def lock_to_flag(self, lock): + return "1" if lock else "-1" + + def flag_to_lock(self, flag): + return flag == "1" + + def modify_user(self, username, pw=None, gid=None, shell=None, visible=None, + lock=None, comment=None): + attributes = [] + if pw is not None: + attributes.append((ldap.MOD_REPLACE, 'userPassword', str(pw))) + if gid is not None: + attributes.append((ldap.MOD_REPLACE, 'gidNumber', str(gid))) + if shell is not None: + attributes.append((ldap.MOD_REPLACE, 'loginShell', shell)) + if comment is not None: + attributes.append((ldap.MOD_REPLACE, 'cn', comment)) + if visible is not None: + attributes.append( + (ldap.MOD_REPLACE, 'shadowFlag', + self.visible_to_flag(visible))) + if lock is not None: + attributes.append( + (ldap.MOD_REPLACE, 'shadowExpire', self.lock_to_flag(lock))) + try: + self.ldap_connect.ldap_modify_attrs( + self.user_dn(username), attributes) + except LDAPConnectError as e: + raise UnixError( + _("Failed to modify user parameters in LDAP: %s") % str(e)) + + def remove_user(self, username): + try: + self.ldap_connect.ldap_remove_dn(self.user_dn(username)) + except LDAPConnectError as e: + raise UnixError(_("Failed to remove user from LDAP: %s") % str(e)) + + class Unix(Ldap): """Основной объект для выполнения действий связанных с настройкой Unix сервиса """ + class Method(object): Setup = "unix_setup" - All = (Setup,) + UserAdd = "unix_useradd" + UserMod = "unix_usermod" + UserDel = "unix_userdel" + UserShow = "unix_usershow" + GroupAdd = "unix_groupadd" + GroupMod = "unix_groupmod" + GroupDel = "unix_groupdel" + GroupShow = "unix_groupshow" + Passwd = "unix_passwd" + All = ( + Setup, UserAdd, UserMod, UserDel, GroupAdd, GroupMod, GroupDel, + Passwd, + UserShow, GroupShow) + + service_name = "unix" def init(self): pass + + def rename_group(self, oldname, newname): + """ + Переименовать группу + """ + if oldname != newname and newname: + ldap_connect = self.clVars.Get('ldap.cl_ldap_connect') + groups_dn = self.clVars.Get('ld_unix_groups_dn') + ug = UnixGroups(ldap_connect, groups_dn) + ug.rename_group(oldname, newname) + return True + + def update_group_comment(self, group, comment): + """ + Переименовать группу + """ + ldap_connect = self.clVars.Get('ldap.cl_ldap_connect') + groups_dn = self.clVars.Get('ld_unix_groups_dn') + ug = UnixGroups(ldap_connect, groups_dn) + ug.update_group_comment(group, comment) + return True + + def update_group_id(self, group, gid, old_gid): + """ + Обновить gid группы + """ + ldap_connect = self.clVars.Get('ldap.cl_ldap_connect') + groups_dn = self.clVars.Get('ld_unix_groups_dn') + ug = UnixGroups(ldap_connect, groups_dn) + ug.update_group_id(group, str(gid)) + + users_dn = self.clVars.Get('ld_unix_users_dn') + uu = UnixUsers(ldap_connect, users_dn) + for user in uu.iterate_ldap_user("gidNumber=%d" % old_gid): + self.printSUCCESS(_("Change primary group for user {user}").format( + user=user.username)) + uu.update_user_group_id(user.username, str(gid)) + return True + + def remove_group(self, groupname): + """ + Удалить группу + """ + ldap_connect = self.clVars.Get('ldap.cl_ldap_connect') + groups_dn = self.clVars.Get('ld_unix_groups_dn') + ug = UnixGroups(ldap_connect, groups_dn) + ug.remove_group(groupname) + return True + + def remove_user(self, username): + """ + Удалить пользователя + """ + ldap_connect = self.clVars.Get('ldap.cl_ldap_connect') + users_dn = self.clVars.Get('ld_unix_users_dn') + uu = UnixUsers(ldap_connect, users_dn) + uu.remove_user(username) + return True + + def add_users_in_group(self, users, groupname): + """ + Добавить пользователей в группу + """ + ldap_connect = self.clVars.Get('ldap.cl_ldap_connect') + groups_dn = self.clVars.Get('ld_unix_groups_dn') + ug = UnixGroups(ldap_connect, groups_dn) + group = ug.search_ldap_group_name(groupname) + if group: + exists_users = group.user_list + new_users = set(users) - set(exists_users) + ug.add_users_to_group(new_users, groupname) + return True + return False + + def remove_users_from_group(self, users, groupname): + """ + Удалить пользователей из групп + """ + ldap_connect = self.clVars.Get('ldap.cl_ldap_connect') + groups_dn = self.clVars.Get('ld_unix_groups_dn') + ug = UnixGroups(ldap_connect, groups_dn) + group = ug.search_ldap_group_name(groupname) + if group: + exists_users = group.user_list + remove_users = set(exists_users) & set(users) + ug.remove_users_from_group(list(remove_users), groupname) + return True + return False + + def add_user_in_groups(self, user, groups): + """ + Добавить пользователя в группы + """ + for group in groups: + self.add_users_in_group([user], group) + return True + + def remove_user_from_groups(self, user, groups): + """ + Удалить пользователя из группы + """ + for group in groups: + self.remove_users_from_group([user], group) + return True + + def modify_user(self, login, pw, gid, shell, visible, lock, comment): + """" + Изменить параметры пользователя в LDAP + """ + ldap_connect = self.clVars.Get('ldap.cl_ldap_connect') + users_dn = self.clVars.Get('ld_unix_users_dn') + uu = UnixUsers(ldap_connect, users_dn) + user = uu.search_ldap_user_name(login) + if user: + params = {} + if gid is not None and user.gid != gid: + params['gid'] = str(gid) + self.printSUCCESS( + _("Changed primary group for user %s") % user.username) + if comment is not None and user.comment != comment: + params['comment'] = comment + self.printSUCCESS( + _("Changed comment for user %s") % user.username) + if pw: + params['pw'] = pw + self.printSUCCESS( + _("Changed password for user %s") % user.username) + if shell and user.shell != shell: + params['shell'] = shell + self.printSUCCESS( + _("Changed shell for user %s") % user.username) + if visible is not None and user.visible != visible: + params['visible'] = visible + if visible: + self.printSUCCESS(_("User %s is visible") % user.username) + else: + self.printSUCCESS(_("User %s is unvisible") % user.username) + if lock is not None and user.lock != lock: + params['lock'] = lock + if lock: + self.printSUCCESS(_("User %s is locked") % user.username) + else: + self.printSUCCESS(_("User %s is unlocked") % user.username) + uu.modify_user(user.username, **params) + else: + raise UnixError(_("User %s not found") % user) + return True + + def move_home_directory(self, homedir, new_homedir): + """ + Преместить домашнюю директорию пользователя + """ + try: + dirname = path.dirname(new_homedir) + if not path.exists(dirname): + os.makedirs(dirname) + os.rename(homedir, new_homedir) + except (OSError, IOError): + raise UnixError(_("Failed to move home directory")) + return True + + def create_home_directory(self, homedir, uid, gid, skel): + """ + Создать домашнюю директорию пользователя + """ + try: + os.makedirs(homedir, 0700) + if path.exists(skel): + for fn in listDirectory(skel): + src_fn = path.join(skel, fn) + dst_fn = path.join(homedir, fn) + if path.isdir(src_fn): + shutil.copytree(src_fn, dst_fn, True) + elif path.islink(src_fn): + link_src = os.readlink(src_fn) + os.symlink(link_src, dst_fn) + else: + shutil.copy2(src_fn, dst_fn) + for root, dns, fns in os.walk(homedir): + for fn in (path.join(root, x) for x in dns + fns): + os.lchown(fn, uid, gid) + os.lchown(homedir, uid, gid) + except (OSError, IOError) as e: + self.printWARNING(str(e)) + raise UnixError(_("Failed to create user home directory")) + return True + + def show_groups(self, fields, count, offset): + + dv = self.clVars + # list_group_name = sorted(dv.Choice('cl_core_group')) + + # if not list_group_name: + # self.printSUCCESS(_("No groups")) + + head = [dv.getInfo(x).label for x in fields] + body = [] + ldap_connect = self.clVars.Get('ldap.cl_ldap_connect') + groups_dn = self.clVars.Get('ld_unix_groups_dn') + ug = UnixGroups(ldap_connect, groups_dn) + + variables_mapping = { + 'ur_unix_group_name': lambda group: group.group_name, + 'ur_unix_group_id': lambda group: str(group.gid), + 'ur_unix_group_comment': lambda group: group.comment, + 'ur_unix_group_users': lambda group: ", ".join(group.user_list) + } + + for group in ug.iterate_ldap_group("cn=*", offset, count): + body.append([variables_mapping.get(x)(group) for x in fields]) + # body.append((group.group_name, str(group.gid), + # group.comment, ",".join(group.user_list))) + + mapping = {'ur_unix_group_name': 'ur_unix_group_name_exists'} + table_fields = [mapping.get(x, '') for x in fields] + if body: + self.printTable( + _("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')) + num_page, count_page = getPagesInterval( + count, offset, int(self.clVars.Get('core.cl_page_max'))) + self.printSUCCESS(_('page %d from ') % num_page + str(count_page)) + else: + self.printSUCCESS(_("No groups")) + return True + + def show_group(self, groupname): + print groupname + dv = self.clVars + list_group_name = sorted(dv.Choice('cl_core_group')) + + if not list_group_name: + self.printSUCCESS(_("No groups")) + + head = [_('Field'), _('Value')] + body = [] + + fields = [ + 'ur_unix_group_name', + 'ur_unix_group_id', + 'ur_unix_group_comment', + 'ur_unix_group_users' + ] + + self.clVars.Set('ur_unix_group_name', groupname, True) + for varname in fields: + varval = self.clVars.Get(varname) + varobj = self.clVars.getInfo(varname) + if "list" in varobj.type: + varval = "\n".join(varval) + + body.append([varobj.label or "", varval]) + + if body: + self.printTable(_("Group info"), head, body) + return True + + def show_users(self, fields, count, offset): + dv = self.clVars + # list_group_name = sorted(dv.Choice('cl_core_group')) + + # if not list_group_name: + # self.printSUCCESS(_("No groups")) + + head = [dv.getInfo(x).label for x in fields] + body = [] + ldap_connect = self.clVars.Get('ldap.cl_ldap_connect') + users_dn = self.clVars.Get('ld_unix_users_dn') + uu = UnixUsers(ldap_connect, users_dn) + groups_dn = self.clVars.Get('ld_unix_groups_dn') + ug = UnixGroups(ldap_connect, groups_dn) + + yesno = lambda x: _("Yes") if x else _("No") + + variables_mapping = { + 'ur_unix_uid': lambda user: user.uid, + 'ur_unix_login': lambda user: user.username, + 'ur_unix_comment': lambda user: user.comment, + 'ur_unix_lock_set': lambda user: yesno(user.lock), + 'ur_unix_visible_set': lambda user: yesno(user.visible), + 'ur_unix_primary_group': lambda user: ug.gid_to_name(str(user.gid)), + 'ur_unix_groups': lambda user: ", ".join( + x.group_name for x in ug.iterate_ldap_group( + "memberUid=%s" % user.username) + ), + 'ur_unix_home_path': lambda user: user.homedir, + 'ur_unix_shell': lambda user: user.shell, + 'ur_unix_pw_set': lambda user: 'HZ', + } + + mapping = {'ur_unix_login': 'ur_unix_login_exists'} + for user in uu.iterate_ldap_user("uid=*", offset, count): + print user + body.append([variables_mapping.get(x)(user) for x in fields]) + table_fields = [mapping.get(x, '') for x in fields] + + if not body: + body = [[]] + dv.Invalidate('ur_unix_user_count') + self.printTable(_("Users") if any(body) else _("No Users"), + 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'))) + num_page, count_page = getPagesInterval( + count, offset, int(self.clVars.Get('unix.ur_unix_user_count'))) + if any(body): + self.printSUCCESS(_('page %d from ') % num_page + str(count_page)) + return True + + def show_user(self, user): + dv = self.clVars + + head = [_('Field'), _('Value')] + body = [] + + fields = [ + 'ur_unix_uid', + 'ur_unix_login', + 'ur_unix_comment', + 'ur_unix_lock_set', + 'ur_unix_visible_set', + 'ur_unix_primary_group', + 'ur_unix_groups', + 'ur_unix_home_path', + 'ur_unix_shell', + 'ur_unix_pw_set', + ] + + self.clVars.Set('ur_unix_login', user, True) + for varname in fields: + varval = self.clVars.Get(varname) + varobj = self.clVars.getInfo(varname) + if "list" in varobj.type: + varval = "\n".join(varval) + + body.append([varobj.label or "", varval]) + + if body: + self.printTable(_("User info"), head, body) + return True + + def try_remove_primary_group(self, user, primary_group): + """ + Primary group + :param primary_group: + :return: + """ + ldap_connect = self.clVars.Get('ldap.cl_ldap_connect') + groups_dn = self.clVars.Get('ld_unix_groups_dn') + ug = UnixGroups(ldap_connect, groups_dn) + filter_str = "gidNumber={0}".format(primary_group) + filter_str2 = "(&(gidNumber={0})(!(uid={1})))".format( + primary_group, user) + group = ug.search_ldap_group(filter_str) + + ldap_connect = self.clVars.Get('ldap.cl_ldap_connect') + users_dn = self.clVars.Get('ld_unix_users_dn') + uu = UnixUsers(ldap_connect, users_dn) + if group: + if not group.user_list and not uu.search_ldap_user(filter_str2): + self.remove_group(group.group_name) + self.printSUCCESS(_("Removed user primary group {0}").format( + group.group_name)) + return True diff --git a/pym/unix/utils/cl_unix_groupadd.py b/pym/unix/utils/cl_unix_groupadd.py new file mode 100644 index 0000000..0677a71 --- /dev/null +++ b/pym/unix/utils/cl_unix_groupadd.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- + +# Copyright 2016 Mir Calculate. http://www.calculate-linux.org +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +from calculate.core.server.func import Action, Tasks +from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate +from calculate.lib.cl_template import TemplatesError +from calculate.lib.utils.files import FilesError +from calculate.lib.datavars import VariableError +from calculate.server.variables.action import Actions +from ..unix import UnixError, Unix +from calculate.ldap.ldap import LdapError +from calculate.ldap.utils.cl_ldap_setup import MetaTasks + +from calculate.ldap.utils.cl_ldap_setup import ClLdapSetupAction + +from calculate.server.server import ServerError + +_ = lambda x: x +setLocalTranslate('cl_unix3', sys.modules[__name__]) +__ = getLazyLocalTranslate(_) + + +class ClUnixGroupaddAction(Action): + """ + Действие обновление конфигурационных файлов + """ + # ошибки, которые отображаются без подробностей + native_error = (FilesError, + TemplatesError, + VariableError, + ServerError, + UnixError, + LdapError) + + successMessage = __("Group {ur_unix_group_name} added in Unix service!") + failedMessage = __("Failed to add {ur_unix_group_name} in Unix server!") + interruptMessage = __("Adding of new group manually interrupted") + + stop_tasks = [ + ] + + meta_tasks = MetaTasks("Unix") + + # список задач для действия + tasks = [ + {'name': 'apply_ldif', + 'tasks': meta_tasks.ldif_task("unix.ld_unix_dn,unix.ld_unix_pw", + Actions.Setup) + }, + ] diff --git a/pym/unix/utils/cl_unix_groupdel.py b/pym/unix/utils/cl_unix_groupdel.py new file mode 100644 index 0000000..c4cd127 --- /dev/null +++ b/pym/unix/utils/cl_unix_groupdel.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- + +# Copyright 2016 Mir Calculate. http://www.calculate-linux.org +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +from calculate.core.server.func import Action, Tasks +from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate +from calculate.lib.cl_template import TemplatesError +from calculate.lib.utils.files import FilesError +from calculate.lib.datavars import VariableError +from calculate.server.variables.action import Actions +from ..unix import UnixError, Unix +from calculate.ldap.ldap import LdapError +from calculate.ldap.utils.cl_ldap_setup import MetaTasks + +from calculate.server.server import ServerError + +_ = lambda x: x +setLocalTranslate('cl_unix3', sys.modules[__name__]) +__ = getLazyLocalTranslate(_) + + +class ClUnixGroupdelAction(Action): + """ + Действие обновление конфигурационных файлов + """ + # ошибки, которые отображаются без подробностей + native_error = (FilesError, + TemplatesError, + VariableError, + ServerError, + UnixError, + LdapError) + + successMessage = __("Group {ur_unix_group_name} deleted from Unix service!") + failedMessage = __( + "Failed to delete {ur_unix_group_name} from Unix server!") + interruptMessage = __("Deleting of group manually interrupted") + + stop_tasks = [ + ] + + meta_tasks = MetaTasks("Unix") + + # список задач для действия + 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_groupmod.py b/pym/unix/utils/cl_unix_groupmod.py new file mode 100644 index 0000000..5d1a002 --- /dev/null +++ b/pym/unix/utils/cl_unix_groupmod.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- + +# Copyright 2016 Mir Calculate. http://www.calculate-linux.org +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +from calculate.core.server.func import Action, Tasks +from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate +from calculate.lib.cl_template import TemplatesError +from calculate.lib.utils.files import FilesError +from calculate.lib.datavars import VariableError +from calculate.server.variables.action import Actions +from ..unix import UnixError, Unix +from calculate.ldap.ldap import LdapError +from calculate.ldap.utils.cl_ldap_setup import MetaTasks + +from calculate.server.server import ServerError + +_ = lambda x: x +setLocalTranslate('cl_unix3', sys.modules[__name__]) +__ = getLazyLocalTranslate(_) + + +class ClUnixGroupmodAction(Action): + """ + Действие обновление конфигурационных файлов + """ + # ошибки, которые отображаются без подробностей + native_error = (FilesError, + TemplatesError, + VariableError, + ServerError, + UnixError, + LdapError) + + successMessage = __("Group {ur_unix_group_name} modified in Unix service!") + failedMessage = __("Failed to modify {ur_unix_group_name} in Unix server!") + interruptMessage = __("Modifing of group manually interrupted") + + stop_tasks = [ + ] + + meta_tasks = MetaTasks("Unix") + + # список задач для действия + tasks = [ + {'name': 'remove_users', + 'message': _("Users {unix.ur_unix_group_users_del} removed " + "from group {unix.ur_unix_group_name}"), + 'method': 'Unix.remove_users_from_group(unix.ur_unix_group_users_del,' + 'unix.ur_unix_group_name_exists)', + 'condition': lambda Get: Get('unix.ur_unix_group_users_del') + }, + {'name': 'append_users', + 'message': _("Users {unix.ur_unix_group_users_add} added " + "to group {unix.ur_unix_group_name}"), + 'method': 'Unix.add_users_in_group(unix.ur_unix_group_users_add,' + 'unix.ur_unix_group_name_exists)', + 'condition': lambda Get: Get('unix.ur_unix_group_users_add') + }, + {'name': 'rename_group', + 'message': _("Rename group {unix.ur_unix_group_name} to " + "{unix.ur_unix_group_newname}"), + 'method': 'Unix.rename_group(unix.ur_unix_group_name,' + 'unix.ur_unix_group_newname)', + 'condition': lambda Get: Get('unix.ur_unix_group_newname') + }, + {'name': 'change_comment', + 'message': _("Changed comment for group {unix.ur_unix_group_name} to " + "{unix.ur_unix_group_comment}"), + 'method': 'Unix.update_group_comment(unix.ur_unix_group_name,' + 'unix.ur_unix_group_comment)', + 'condition': lambda Get: Get('unix.ur_unix_group_comment') != Get( + 'unix.ur_unix_group_comment_exists') + }, + {'name': 'group_change_id', + 'message': _("Changes ID for group {unix.ur_unix_group_name} " + "to {unix.ur_unix_group_id}"), + 'method': 'Unix.update_group_id(unix.ur_unix_group_name,' + 'unix.ur_unix_group_id,unix.ur_unix_group_id_exists)', + 'condition': lambda Get: (Get('unix.ur_unix_group_id') != Get( + 'unix.ur_unix_group_id_exists')) + }, + ] diff --git a/pym/unix/utils/cl_unix_groupshow.py b/pym/unix/utils/cl_unix_groupshow.py new file mode 100644 index 0000000..b2473b5 --- /dev/null +++ b/pym/unix/utils/cl_unix_groupshow.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- + +# Copyright 2016 Mir Calculate. http://www.calculate-linux.org +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +from calculate.core.server.func import Action, Tasks +from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate +from calculate.lib.cl_template import TemplatesError +from calculate.lib.utils.files import FilesError +from calculate.lib.datavars import VariableError +from calculate.server.variables.action import Actions +from ..unix import UnixError, Unix +from calculate.ldap.ldap import LdapError +from calculate.ldap.utils.cl_ldap_setup import MetaTasks + +from calculate.server.server import ServerError + +_ = lambda x: x +setLocalTranslate('cl_unix3', sys.modules[__name__]) +__ = getLazyLocalTranslate(_) + + +class ClUnixGroupshowAction(Action): + """ + Действие обновление конфигурационных файлов + """ + # ошибки, которые отображаются без подробностей + native_error = (FilesError, + TemplatesError, + VariableError, + ServerError, + UnixError, + LdapError) + + successMessage = None + failedMessage = None + interruptMessage = __("Viewing manually interrupted") + + meta_tasks = MetaTasks("Unix") + + # список задач для действия + tasks = [ + {'name': 'view_groups', + 'method': 'Unix.show_groups(unix.cl_unix_group_show_fields,' + 'core.cl_page_count,core.cl_page_offset)', + 'condition': lambda Get: Get('ur_unix_group_show') == "all" + }, + {'name': 'view_group', + 'method': 'Unix.show_group(ur_unix_group_show)', + 'condition': lambda Get: Get('ur_unix_group_show') != "all" + } + ] diff --git a/pym/unix/utils/cl_unix_passwd.py b/pym/unix/utils/cl_unix_passwd.py new file mode 100644 index 0000000..19f556a --- /dev/null +++ b/pym/unix/utils/cl_unix_passwd.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- + +# Copyright 2016 Mir Calculate. http://www.calculate-linux.org +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +from calculate.core.server.func import Action, Tasks +from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate +from calculate.lib.cl_template import TemplatesError +from calculate.lib.utils.files import FilesError +from calculate.lib.datavars import VariableError +from calculate.server.variables.action import Actions +from ..unix import UnixError, Unix +from calculate.ldap.ldap import LdapError +from calculate.ldap.utils.cl_ldap_setup import MetaTasks + +from calculate.server.server import ServerError + +_ = lambda x: x +setLocalTranslate('cl_unix3', sys.modules[__name__]) +__ = getLazyLocalTranslate(_) + + +class ClUnixPasswdAction(Action): + """ + Действие обновление конфигурационных файлов + """ + # ошибки, которые отображаются без подробностей + native_error = (FilesError, + TemplatesError, + VariableError, + ServerError, + UnixError, + LdapError) + + successMessage = __("Password for user {ur_unix_login} in Unix service changed!") + failedMessage = __("Failed to change password for user {ur_unix_login} in Unix server!") + interruptMessage = __("User password changing manually interrupted") + + stop_tasks = [ + ] + + meta_tasks = MetaTasks("Unix") + + # список задач для действия + tasks = [ + {'name': 'user_change', + 'method': 'Unix.modify_user(ur_unix_login,ur_unix_hash,' + '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 2acdbba..72895c5 100644 --- a/pym/unix/utils/cl_unix_setup.py +++ b/pym/unix/utils/cl_unix_setup.py @@ -22,7 +22,11 @@ from calculate.lib.utils.files import FilesError from calculate.lib.datavars import VariableError from calculate.server.variables.action import Actions from ..unix import UnixError, Unix -from calculate.ldap.ldap import LdapError +from calculate.ldap.ldap import LdapError, Ldap +from calculate.ldap.utils.cl_ldap_setup import MetaTasks + +from calculate.ldap.utils.cl_ldap_setup import ClLdapSetupAction + from calculate.server.server import ServerError _ = lambda x: x @@ -46,6 +50,57 @@ class ClUnixSetupAction(Action): failedMessage = __("Failed to configure Unix server!") interruptMessage = __("Unix server configuration manually interrupted") + stop_tasks = [ + ] + + meta_tasks = MetaTasks("Unix") + + uninstall_tasks = [ + {'name': 'clear_creds', + 'method': 'Server.clear_service_data("unix")' + }, + {'name': 'unset_ldap', + 'method': 'Server.service_uninstall("unix")' + }, + ] + # список задач для действия tasks = [ + {'name': 'set_ldif', + 'method': 'Unix.set_ldap_connection(' + 'ldap.ld_admin_dn,ldap.ld_admin_pw)', + }, + {'name': 'remove_old_db', + 'method': 'Unix.remove_ldap_branch(ld_unix_dn)', + 'condition': lambda Get: Get('server.sr_unix_set') == 'on' + }, + {'name': 'uninstall', + 'tasks': uninstall_tasks, + 'condition': lambda Get: Get('server.sr_unix_set') == 'on' + }, + {'name': 'apply_ldif', + 'tasks': meta_tasks.ldif_task("ldap.ld_admin_dn,ldap.ld_admin_pw", + Actions.Setup) + }, + {'name': 'templates', + 'message': __("Configure LDAP"), + 'method': 'Server.applyTemplates(install.cl_source,' + 'False,True,None,True,True)', + }, + {'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, + }, + #{'name': 'save_data', + # 'method': 'Unix.save_variables()' + # } ] + + ClLdapSetupAction.register_stop(stop_tasks) + ClLdapSetupAction.register_uninstall(uninstall_tasks) diff --git a/pym/unix/utils/cl_unix_useradd.py b/pym/unix/utils/cl_unix_useradd.py new file mode 100644 index 0000000..f3ffcad --- /dev/null +++ b/pym/unix/utils/cl_unix_useradd.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- + +# Copyright 2016 Mir Calculate. http://www.calculate-linux.org +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +from calculate.core.server.func import Action, Tasks +from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate +from calculate.lib.cl_template import TemplatesError +from calculate.lib.utils.files import FilesError +from calculate.lib.datavars import VariableError +from calculate.server.variables.action import Actions +from ..unix import UnixError, Unix +from calculate.ldap.ldap import LdapError +from calculate.ldap.utils.cl_ldap_setup import MetaTasks + +from calculate.ldap.utils.cl_ldap_setup import ClLdapSetupAction + +from calculate.server.server import ServerError + +_ = lambda x: x +setLocalTranslate('cl_unix3', sys.modules[__name__]) +__ = getLazyLocalTranslate(_) + + +class ClUnixUseraddAction(Action): + """ + Действие обновление конфигурационных файлов + """ + # ошибки, которые отображаются без подробностей + native_error = (FilesError, + TemplatesError, + VariableError, + ServerError, + UnixError, + LdapError) + + successMessage = __("User {ur_unix_login} added in Unix service!") + failedMessage = __("Failed to add {ur_unix_login} in Unix server!") + interruptMessage = __("Adding of new user manually interrupted") + + stop_tasks = [ + ] + + meta_tasks = MetaTasks("Unix") + + # список задач для действия + tasks = [ + {'name': 'apply_ldif', + 'tasks': meta_tasks.ldif_task("unix.ld_unix_dn,unix.ld_unix_pw", + Actions.Setup) + }, + {'name': 'user_groups', + 'method': 'Unix.add_user_in_groups(ur_unix_login,ur_unix_groups)', + 'condition': lambda Get: Get('ur_unix_groups') + }, + {'name': 'create_homedir', + 'message': _("Create user home directory {unix.ur_unix_home_path}"), + 'method': 'Unix.create_home_directory(unix.ur_unix_home_path,' + 'unix.ur_unix_uid,unix.ur_unix_gid,ur_unix_skel)', + 'condition': lambda Get: Get('unix.ur_unix_create_home_set') == 'on' + }, + ] diff --git a/pym/unix/utils/cl_unix_userdel.py b/pym/unix/utils/cl_unix_userdel.py new file mode 100644 index 0000000..7ba448f --- /dev/null +++ b/pym/unix/utils/cl_unix_userdel.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- + +# Copyright 2016 Mir Calculate. http://www.calculate-linux.org +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +from calculate.core.server.func import Action, Tasks +from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate +from calculate.lib.cl_template import TemplatesError +from calculate.lib.utils.files import FilesError +from calculate.lib.datavars import VariableError +from calculate.server.variables.action import Actions +from ..unix import UnixError, Unix +from calculate.ldap.ldap import LdapError +from calculate.ldap.utils.cl_ldap_setup import MetaTasks + +from calculate.server.server import ServerError + +_ = lambda x: x +setLocalTranslate('cl_unix3', sys.modules[__name__]) +__ = getLazyLocalTranslate(_) + + +class ClUnixUserdelAction(Action): + """ + Действие обновление конфигурационных файлов + """ + # ошибки, которые отображаются без подробностей + native_error = (FilesError, + TemplatesError, + VariableError, + ServerError, + UnixError, + LdapError) + + successMessage = __("User {ur_unix_login} deleted from Unix service!") + failedMessage = __( + "Failed to delete {ur_unix_login} from Unix server!") + interruptMessage = __("Deleting of user manually interrupted") + + stop_tasks = [ + ] + + meta_tasks = MetaTasks("Unix") + + # список задач для действия + 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') + }, + {'name': 'remove_primary_group', + 'method': 'Unix.try_remove_primary_group(unix.ur_unix_login,' + 'unix.ur_unix_gid)' + }, + {'name': 'remove_user', + 'method': 'Unix.remove_user(unix.ur_unix_login)' + }, + ] diff --git a/pym/unix/utils/cl_unix_usermod.py b/pym/unix/utils/cl_unix_usermod.py new file mode 100644 index 0000000..45a54c7 --- /dev/null +++ b/pym/unix/utils/cl_unix_usermod.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- + +# Copyright 2016 Mir Calculate. http://www.calculate-linux.org +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +from calculate.core.server.func import Action, Tasks +from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate +from calculate.lib.cl_template import TemplatesError +from calculate.lib.utils.files import FilesError +from calculate.lib.datavars import VariableError +from calculate.server.variables.action import Actions +from ..unix import UnixError, Unix +from calculate.ldap.ldap import LdapError +from calculate.ldap.utils.cl_ldap_setup import MetaTasks + +from calculate.server.server import ServerError + +_ = lambda x: x +setLocalTranslate('cl_unix3', sys.modules[__name__]) +__ = getLazyLocalTranslate(_) + + +class ClUnixUsermodAction(Action): + """ + Действие обновление конфигурационных файлов + """ + # ошибки, которые отображаются без подробностей + native_error = (FilesError, + TemplatesError, + VariableError, + ServerError, + UnixError, + LdapError) + + successMessage = __("User {ur_unix_login} modified in Unix service!") + failedMessage = __("Failed to modify user {ur_unix_login} in Unix server!") + interruptMessage = __("Modifing of user manually interrupted") + + stop_tasks = [ + ] + + meta_tasks = MetaTasks("Unix") + + # список задач для действия + tasks = [ + {'name': 'user_change', + 'method': 'Unix.modify_user(ur_unix_login,ur_unix_pw,ur_unix_gid,' + 'ur_unix_shell,ur_unix_visible_set,ur_unix_lock_set,' + 'ur_unix_comment)', + }, + {'name': 'remove_groups', + 'message': _("User {unix.ur_unix_login} removed from " + "groups {unix.ur_unix_groups_del}"), + 'method': 'Unix.remove_user_from_groups(unix.ur_unix_login,' + 'unix.ur_unix_groups_del)', + 'condition': lambda Get: Get('unix.ur_unix_groups_del') + }, + {'name': 'append_groups', + 'message': _("User {unix.ur_unix_login} added " + "to groups {unix.ur_unix_groups_add}"), + 'method': 'Unix.add_user_in_groups(unix.ur_unix_login,' + 'unix.ur_unix_groups_add)', + 'condition': lambda Get: Get('unix.ur_unix_groups_add') + }, + {'name': 'move_homedir', + 'message': _("User home directory {unix.ur_unix_home_path_exists} " + "moved to {unix.ur_unix_home_path}"), + 'method': 'Unix.move_home_directory(unix.ur_unix_home_path_exists,' + 'unix.ur_unix_home_path)', + 'condition': lambda Get: Get('unix.ur_unix_home_path_move') == 'on' + }, + # {'name': 'apply_ldif', + # 'tasks': meta_tasks.ldif_task("unix.ld_unix_dn,unix.ld_unix_pw", + # Actions.Setup) + # }, + # {'name': 'user_groups', + # 'method': 'Unix.add_user_in_groups(ur_unix_login,ur_unix_groups)', + # 'condition': lambda Get: Get('ur_unix_groups') + # }, + ] diff --git a/pym/unix/utils/cl_unix_usershow.py b/pym/unix/utils/cl_unix_usershow.py new file mode 100644 index 0000000..54bc5b6 --- /dev/null +++ b/pym/unix/utils/cl_unix_usershow.py @@ -0,0 +1,64 @@ +# -*- coding: utf-8 -*- + +# Copyright 2016 Mir Calculate. http://www.calculate-linux.org +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +from calculate.core.server.func import Action, Tasks +from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate +from calculate.lib.cl_template import TemplatesError +from calculate.lib.utils.files import FilesError +from calculate.lib.datavars import VariableError +from calculate.server.variables.action import Actions +from ..unix import UnixError, Unix +from calculate.ldap.ldap import LdapError +from calculate.ldap.utils.cl_ldap_setup import MetaTasks + +from calculate.server.server import ServerError + +_ = lambda x: x +setLocalTranslate('cl_unix3', sys.modules[__name__]) +__ = getLazyLocalTranslate(_) + + +class ClUnixUsershowAction(Action): + """ + Действие обновление конфигурационных файлов + """ + # ошибки, которые отображаются без подробностей + native_error = (FilesError, + TemplatesError, + VariableError, + ServerError, + UnixError, + LdapError) + + successMessage = None + failedMessage = None + interruptMessage = __("Viewing manually interrupted") + + meta_tasks = MetaTasks("Unix") + + # список задач для действия + tasks = [ + {'name': 'view_users', + 'method': 'Unix.show_users(unix.cl_unix_user_show_fields,' + 'core.cl_page_count,core.cl_page_offset)', + 'condition': lambda Get: Get('ur_unix_user_show') == "all" + }, + {'name': 'view_user', + 'method': 'Unix.show_user(ur_unix_user_show)', + 'condition': lambda Get: Get('ur_unix_user_show') != "all" + } + ] diff --git a/pym/unix/variables/action.py b/pym/unix/variables/action.py index 3874fda..5e62043 100644 --- a/pym/unix/variables/action.py +++ b/pym/unix/variables/action.py @@ -15,8 +15,28 @@ # limitations under the License. import sys -from calculate.lib.datavars import ActionVariable +from calculate.lib.datavars import (VariableError, Variable) from calculate.lib.cl_lang import setLocalTranslate +from helpers import UnixGroupHelper, UnixUserHelper, Actions +_ = lambda x: x setLocalTranslate('cl_unix3', sys.modules[__name__]) + + +class VariableClUnixAction(UnixGroupHelper, UnixUserHelper, Variable): + """ + Дополнительный тип действия для переменной + """ + value = "" + + def check(self, value): + 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(): + raise VariableError(_("Unix service has not groups")) + diff --git a/pym/unix/variables/helpers.py b/pym/unix/variables/helpers.py new file mode 100644 index 0000000..b14524e --- /dev/null +++ b/pym/unix/variables/helpers.py @@ -0,0 +1,174 @@ +# -*- coding: utf-8 -*- + +# Copyright 2016 Mir Calculate. http://www.calculate-linux.org +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +from calculate.lib.datavars import (VariableInterface, VariableError) +from calculate.unix.unix import UnixGroups, UnixUsers + +_ = lambda x: x +from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate) + +setLocalTranslate('cl_unix3', sys.modules[__name__]) +__ = getLazyLocalTranslate(_) + + +class Actions(object): + UserAdd = "useradd" + UserMod = "usermod" + UserDel = "userdel" + GroupAdd = "groupadd" + GroupMod = "groupmod" + GroupDel = "groupdel" + Passwd = "passwd" + Setup = "setup" + GroupShow = "groupshow" + UserShow = "usershow" + + UserExists = (UserMod, UserDel, Passwd) + GroupExists = (GroupMod, GroupDel) + All = ( + UserAdd, UserMod, UserDel, GroupAdd, GroupMod, GroupDel, Setup, Passwd) + New = (UserAdd, GroupAdd) + Exists = (Passwd, UserMod, UserDel, GroupMod, GroupDel, UserShow, GroupShow) + + +class ExistsUserHelper(VariableInterface): + attribute = "" + + def get_exists(self): + user = self.Get('ur_unix_user_object') + if user: + val = getattr(user, self.attribute) + if type(val) == bool: + return "on" if val else "off" + else: + return val + return "" + + +class UnixGroupHelper(VariableInterface, UnixGroups): + exception = VariableError + + @property + def ldap_connect(self): + return self.Get('ldap.cl_ldap_connect') + + @property + def groups_dn(self): + return self.Get('ld_unix_groups_dn') + + +class UnixUserHelper(VariableInterface, UnixUsers): + exception = VariableError + + @property + def ldap_connect(self): + return self.Get('ldap.cl_ldap_connect') + + @property + def users_dn(self): + return self.Get('ld_unix_users_dn') + + +class UnixUserPropertyHelper(VariableInterface): + """ + Получение атрибутов текущего пользователя + """ + + +class UnixActionHelper(VariableInterface): + """ + Разделение на методы в зависимости от действия + """ + fallback = "" + + def get_new(self): + if "list" in self.type: + return [] + return "" + + def get_exists(self): + if "list" in self.type: + return [] + return "" + + def check_new(self, value): + pass + + def check_exists(self, value): + pass + + def choice_new(self): + return [] + + def choice_exists(self): + return [] + + def _new(self, value): + return value in Actions.New + + def _exists(self, value): + return value in Actions.Exists + + def get(self): + unix_action = self.Get('unix.cl_unix_action') + if self._new(unix_action): + return self.get_new() + elif self._exists(unix_action): + return self.get_exists() + return self.fallback + + def check(self, value): + unix_action = self.Get('unix.cl_unix_action') + if self._new(unix_action): + return self.check_new(value) + elif self._exists(unix_action): + return self.check_exists(value) + + def choice(self): + unix_action = self.Get('unix.cl_unix_action') + if self._new(unix_action): + return self.choice_new() + elif self._exists(unix_action): + return self.choice_exists() + +class FieldsHelper(VariableInterface): + type = "choice-list" + element = "selecttable" + opt = ["--fields"] + metavalue = "FIELDS" + alias_variable = "" + + def init(self): + self.label = _("Fields") + self.help = _("fields for display") + + def choice(self): + data = self.Get(self.alias_variable) + return [(x, self.parent.getInfo(y).label) for x, y in data] + + def get(self): + return [x for x, y in self.Get(self.alias_variable)] + + +class ShowFieldsHelper(VariableInterface): + type = "list" + alias_variable = "" + source_variable = "" + + def get(self): + mapping = dict(self.Get(self.alias_variable)) + return [mapping[x] for x in self.Get(self.source_variable)] diff --git a/pym/unix/variables/unix.py b/pym/unix/variables/unix.py index c60451c..0e8abf1 100644 --- a/pym/unix/variables/unix.py +++ b/pym/unix/variables/unix.py @@ -15,10 +15,18 @@ # limitations under the License. import sys +from os import path +from calculate.lib.cl_ldap import LDAPConnectError from calculate.lib.datavars import (ReadonlyVariable, Variable, - VariableInterface, VariableError) -from calculate.lib.utils.common import genpassword -from calculate.lib.utils.tools import repeater + VariableError, PasswordError) +from calculate.ldap.variables.helpers import (HashHelper, RandomPasswordHelper, + ServerEnvHelper, LdapSearchHelper, + LdapMaxHelper) +from calculate.unix.variables.helpers import (UnixUserHelper, UnixGroupHelper, + ExistsUserHelper, + ShowFieldsHelper, + FieldsHelper, UnixActionHelper) +from .action import Actions _ = lambda x: x from calculate.lib.cl_lang import (setLocalTranslate, getLazyLocalTranslate) @@ -27,25 +35,1165 @@ setLocalTranslate('cl_unix3', sys.modules[__name__]) __ = getLazyLocalTranslate(_) -class HashHelper(VariableInterface): +class VariableLdUnixLogin(ReadonlyVariable): """ - Хэш пароля для LDAP + Имя администратор Unix сервера """ - source = "" - hash_var = "ld_encrypt" + value = "Unix" - def get(self): - return SlapPasswd(self.Get(self.hash_var)).get_hash( - self.Get(self.source)) + +# class VariableLdUnixDn(ServerEnvHelper, ReadonlyVariable): +# """ +# DN настроенного сервиса +# """ +# fallback_variable = "unix.ld_unix_dn" +# service = "unix" +# parameter = "dn" + + +class VariableLdUnixDn(ReadonlyVariable): + """ + DN сервиса + """ + value_format = "ou={ld_unix_login},{ldap.ld_services_dn}" -class RandomPasswordHelper(VariableInterface): +class VariableLdUnixUsersDn(ReadonlyVariable): """ - Генератор пароля + DN пользователей сервиса + """ + value_format = "ou=Users,{ld_unix_dn}" + + +class VariableLdUnixGroupsDn(ReadonlyVariable): + """ + DN групп сервиса + """ + value_format = "ou=Groups,{ld_unix_dn}" + + +class VariableLdUnixHash(HashHelper, ReadonlyVariable): + """ + Хэш рут пароля + """ + source = "ld_unix_pw" + + +class VariableLdUnixPw(ServerEnvHelper, RandomPasswordHelper, Variable): + """ + Пароль root """ password_len = 9 + service = "unix" + parameter = "pass" + + @property + def fallback_value(self): + return "test22" + return RandomPasswordHelper.get(self) + + +class VariableUrUnixLogin(UnixUserHelper, UnixActionHelper, Variable): + """ + Логин настраиваемого пользователя + """ + untrusted = True + opt = ("ur_unix_login",) + metavalue = "USER" + + def init(self): + self.label = _("Login") + self.help = _("set user login") + + def get_new(self): + return "" + + def get_exists(self): + return self.Get('ur_unix_login_exists') + + def check_new(self, value): + if not value: + raise VariableError(_("You should specify login")) + if self.search_ldap_user_name(value): + raise VariableError(_("User %s already exists" % value)) + if self.search_system_user_name(value): + raise VariableError( + _("User %s already exists in /etc/passwd") % value) + + +class VariableUrUnixLoginExists(UnixUserHelper, UnixActionHelper, Variable): + """ + Логин настраиваемого пользователя + """ + type = "choice" + opt = ("ur_unix_login_exists",) + metavalue = "USER" + untrusted = True + guitype = "readonly" + + def init(self): + self.label = _("Login") + self.help = _("set user login") + + def get_new(self): + return "" + + def get_exists(self): + return "" + + def choice_exists(self): + return ((user.username, + "%s (%s)" % (user.username, user.comment)) + for user in self.iterate_ldap_user("uid=*")) + + def raiseWrongChoice(self, name, choiceVal, value, error): + if not value: + raise VariableError(_("Please specify user login")) + else: + raise VariableError(_("%s user not found") % value) + + +class VariableUrUnixGroupName(LdapSearchHelper, UnixActionHelper, Variable): + """ + Логин настраиваемого пользователя + """ + base_dn = "{ld_unix_groups_dn}" + search_filter = '(cn={value})' + + untrusted = True + opt = ("ur_unix_group_name",) + metavalue = "GROUP" + + def init(self): + self.label = _("Group") + self.help = _("set the group name") + + def get_new(self): + return "" + + def get_exists(self): + return self.Get('ur_unix_group_name_exists') + + def check(self, value): + if not value: + raise VariableError(_("You should specify group name")) + if self.check_name(value): + raise VariableError(_("Group name already exists")) + + +class VariableUrUnixGroupLabel(ReadonlyVariable): + """ + Информационное поле для закладки + """ + type = "label" + + def init(self): + self.label = _("Group") + + def get(self): + return self.Get('ur_unix_group_name') + + def uncompatible(self): + return self.label + + +class VariableUrUnixGroupNameExists(UnixUserHelper, UnixGroupHelper, Variable): + """ + Логин настраиваемого пользователя + """ + type = "choice" + base_dn = "{ld_unix_groups_dn}" + search_filter = '(cn={value})' + guitype = "hidden" + + untrusted = True + opt = ("ur_unix_group_name_exists",) + metavalue = "GROUP" + + def init(self): + self.label = _("Group") + self.help = _("set the group name") + + def choice(self): + if self.Get('cl_unix_action') == Actions.GroupDel: + primary_groups = map(int, self.get_primary_gids()) + return [(group.group_name, + "%s (%s)" % (group.group_name, group.comment)) + for group in self.iterate_ldap_group("cn=*") + if group.gid not in primary_groups] + else: + return [(group.group_name, + "%s (%s)" % (group.group_name, group.comment)) + for group in self.iterate_ldap_group("cn=*")] + + def raiseWrongChoice(self, name, choiceVal, value, error): + if self.Get('cl_unix_action') == Actions.GroupDel: + group = self.search_ldap_group_name(value) + if group: + users = ", ".join(user.username for user in + self.iterate_ldap_user( + "gidNumber=%d" % group.gid)) + if users: + raise VariableError( + _("Group {group} is primary group for users {users}" + ).format(group=value, users=users)) + if not value: + raise VariableError(_("Choice group")) + raise VariableError(_("Group %s not found") % value) + + +class VariableUrUnixBaseDir(Variable): + """ + Базовая директория для нового пользователя + """ + value = "/home" + opt = ('-b', '--base-dir') + metavalue = "BASE_DIR" + + def init(self): + self.label = _("Base directory") + self.help = _("base directory for the home directory of new account") + + +class VariableUrUnixComment(ExistsUserHelper, UnixActionHelper, Variable): + """ + Описание учётной записи + """ + attribute = "comment" + value_format = "{ldap.ld_base_root.capitalize()} user" + opt = ('-c', '--comment') + metavalue = "COMMENT" + + def init(self): + self.label = _("Comment") + self.help = _("set comment of the account") + + def get_new(self): + return self._value_formatter.format(self.value_format, self.Get) + + +class VariableUrUnixGroupComment(UnixGroupHelper, UnixActionHelper, Variable): + """ + Комментарий к группе + """ + value_format = "{ldap.ld_base_root.capitalize()} group" + opt = ('-c', '--comment') + metavalue = "COMMENT" + + def init(self): + self.label = _("Comment") + self.help = _("set comment of the group") + + def get_new(self): + return self._value_formatter.format(self.value_format, self.Get) + + def get_exists(self): + return self.Get('ur_unix_group_comment_exists') + + +class VariableUrUnixGroupCount(UnixGroupHelper, UnixActionHelper, + ReadonlyVariable): + """ + Количество групп + """ + type = "int" + + def get_exists(self): + return len(self.ldap_group_list()) + + +class VariableUrUnixGroupCommentExists(UnixGroupHelper, UnixActionHelper, + Variable): + """ + Комментарий к группе + """ + + def get_exists(self): + group_name = self.Get('ur_unix_group_name') + if group_name: + group = self.search_ldap_group_name(group_name) + if group: + return group.comment + return "" + + +class VariableUrUnixHomePath(ExistsUserHelper, UnixActionHelper, Variable): + """ + Путь до домашней директории + """ + value_format = "{unix.ur_unix_base_dir}/{unix.ur_unix_login}" + opt = ('-d', '--home-dir') + metavalue = "HOME_DIR" + check_after = ["ur_unix_login"] + + def init(self): + self.label = _("Home directory") + self.help = _("set home directory of the account") + + def get_exists(self): + return self.Get('ur_unix_home_path_exists') + + def get_new(self): + return self._value_formatter.format(self.value_format, self.Get) + + def check_exists(self, value): + if "," in value: + raise VariableError(_("Wrong home directory")) + if not value.startswith('/'): + raise VariableError(_("Home directory path must be absolutly")) + + +class VariableUrUnixHomePathExists(ExistsUserHelper, UnixActionHelper, + ReadonlyVariable): + """ + Путь до домашней директории + """ + attribute = "homedir" + + +class VariableUrUnixHomePathMove(Variable): + """ + Перемещать домашнуюю пользовательскую директорию + """ + type = "bool" + opt = ('-m', '--move-home') + value = "off" + + def init(self): + self.label = _("Move home directory") + self.help = _("move contents of the home directory to the new location") + + def check_on(self): + new_path = self.Get('ur_unix_home_path') + old_path = self.Get('ur_unix_home_path_exists') + if new_path == old_path: + raise VariableError(_("You should change home directory")) + if path.exists(new_path): + raise VariableError( + _("New home directory %s exists") % new_path) + if not path.exists(old_path): + raise VariableError( + _("Previous home directory %s not found") % old_path) + + +class VariableUrUnixPrimaryGroup(ExistsUserHelper, UnixGroupHelper, + UnixActionHelper, Variable): + """ + ID основной группы + """ + attribute = "gid" + type = "choiceedit" + opt = ('-g', '--gid') + metavalue = "GROUP" + + default_value = "default" + + def init(self): + self.label = _("Primary group") + self.help = _("set name or ID of primary group of the account " + "('default' value for create default group)") + + def get_new(self): + return self.default_value + + def get_exists(self): + value = str(ExistsUserHelper.get_exists(self)) + if value: + return str(self.gid_to_name(value)) + + def set(self, value): + if self._new(self.Get('cl_unix_action')): + if value == self.Get('ur_unix_login'): + return self.default_value + return str(self.gid_to_name(value)) + + def choice_new(self): + return ([(self.default_value, _("Default"))] + + self.ldap_group_list()) + + def choice_exists(self): + return self.ldap_group_list() + + def check_new(self, value): + if not value: + raise VariableError(_("You should specify primary group ID")) + # if value != "auto": + if value != self.default_value: + self.check_group(value) + + def check_exists(self, value): + if not value: + raise VariableError(_("You should specify primary group ID")) + # if value != "auto": + if value: + self.check_group(value) + + def raiseWrongChoice(self, name, choiceVal, value, error): + raise VariableError(_("Group %s not found") % value) + + +class VariableUrUnixGid(UnixGroupHelper, ReadonlyVariable): + """ + ID основной группы пользователя + """ + type = "int" def get(self): - return genpassword(self.password_len).strip() + group_name = self.Get('ur_unix_primary_group') + print group_name + if (group_name and + group_name != VariableUrUnixPrimaryGroup.default_value): + ldap_group = self.search_ldap_group_name(group_name) + return str(ldap_group.gid) + else: + return self.Get('ur_unix_next_gid') + +class VariableUrUnixGroupId(LdapSearchHelper, UnixActionHelper, Variable): + """ + ID группы + """ + base_dn = "{ld_unix_groups_dn}" + search_filter = '(gidNumber={value})' + type = "int" + opt = ('-g', '--gid') + metavalue = "GID" + + def init(self): + self.label = _("Group ID") + self.help = _("set the group ID") + + def get_new(self): + return self.Get('ur_unix_next_gid') + + def get_exists(self): + return self.Get('ur_unix_group_id_exists') + + def check_new(self, value): + if not value: + raise VariableError(_("You should specify group ID")) + if self.check_name(value): + raise VariableError(_("Group ID already exists")) + + def check_exists(self, value): + old_value = self.Get('ur_unix_group_id_exists') + if not value: + raise VariableError(_("You should specify group ID")) + if value != old_value and self.check_name(value): + raise VariableError(_("Group ID already exists")) + + +class VariableUrUnixGroupIdExists(UnixGroupHelper, LdapSearchHelper, + UnixActionHelper, Variable): + """ + ID группы + """ + type = "int" + def get_exists(self): + group_name = self.Get('ur_unix_group_name') + if group_name: + group = self.search_ldap_group_name(group_name) + if group: + return str(group.gid) + return "" + + +class VariableUrUnixUid(UnixUserHelper, UnixActionHelper, Variable): + """ + UID пользователя + """ + type = "int" + opt = ('-u', '--uid') + metavalue = "UID" + value = "" + + def init(self): + self.label = _("User ID") + self.help = _("set user ID of the account") + + def get_new(self): + return self.Get('ur_unix_next_uid') + + def get_exists(self): + login = self.Get('ur_unix_login') + if login: + return str(self.search_ldap_user_name(login).uid) + + def check_new(self, value): + user = self.search_ldap_user_id(value) + if user: + raise VariableError(_("Uid %s is used by user %s") + % (user.uid, user.username)) + user = self.search_system_user_id(value) + if user: + raise VariableError(_("Uid %s is used by system user %s") + % (user.uid, user.username)) + + +class VariableUrUnixGroups(UnixGroupHelper, UnixActionHelper, Variable): + """ + Список груп + """ + type = "choiceedit-list" + opt = ("-G", "--groups") + metavalue = "GROUPS" + value = [] + + def init(self): + self.label = _("Supplimentary groups") + self.help = _("set list of supplementary groups of the account") + + def set(self, value): + return map(self.gid_to_name, value) + + def get_exists(self): + return self.Get('ur_unix_groups_exists') + + def choice(self): + return self.ldap_group_list() + + def check(self, value): + for group in value: + self.check_group(group) + + +class VariableUrUnixGroupsExists(UnixGroupHelper, UnixActionHelper, Variable): + """ + Список груп + """ + type = "list" + value = [] + + #def get_bylogin(self, login, obj): + # return [x.group_name for x in + # self.iterate_ldap_group("memberUid=%s" % login)] + + def get_exists(self): + login = self.Get('ur_unix_login') + if login: + return [x.group_name for x in + self.iterate_ldap_group("memberUid=%s" % login)] + return [] + + +class VariableUrUnixGroupsAdd(UnixGroupHelper, UnixActionHelper, Variable): + """ + Список групп в которые необходимо добавить пользователя + """ + type = "choiceedit-list" + opt = ("-a", "--append") + metavalue = "GROUPS" + value = [] + + def init(self): + self.label = _("Include to groups") + self.help = _("include user into groups") + + def set(self, value): + return map(self.gid_to_name, value) + + def get_exists(self): + exists_groups = set(self.Get('ur_unix_groups_exists')) + replace_group = set(self.Get('ur_unix_groups')) + return sorted(list(replace_group - exists_groups)) + + def choice_exists(self): + login = self.Get('ur_unix_login') + if login: + exists_groups = self.Get('ur_unix_groups_exists') + return (x for x in self.ldap_group_list() + if x[0] not in exists_groups) + return [] + + def check_exists(self, value): + exists_groups = self.Get('ur_unix_groups_exists') + replace_groups = self.Get('ur_unix_groups') + if set(exists_groups) != set(replace_groups): + raise VariableError(_( + "Appending user to groups unavailable " + "with the replace groups using")) + login = self.Get('ur_unix_login') + groups = self.ldap_group_names() + failed = [x for x in value if x not in groups] + if failed: + raise VariableError( + _("Wrong groups {groups}").format( + groups=", ".join(failed))) + self.check_special(value, exists_groups, login) + + def check_special(self, value, exists_groups, login): + already_exists = [x for x in value if x in exists_groups] + if already_exists: + raise VariableError( + _("User {user} already exist in groups {groups}").format( + groups=", ".join(already_exists), user=login)) + + def humanReadable(self): + if not self.Get(): + return _("Not change") + + +class VariableUrUnixGroupsDel(VariableUrUnixGroupsAdd): + """ + Список групп из которых необходимо исключить пользователя + """ + type = "choiceedit-list" + opt = ("-r", "--remove") + metavalue = "GROUPS" + value = [] + + def init(self): + self.label = _("Exclude from groups") + self.help = _("exclude user from groups") + + def get_exists(self): + exists_groups = set(self.Get('ur_unix_groups_exists')) + replace_groups = set(self.Get('ur_unix_groups')) + return sorted(list(exists_groups - replace_groups)) + + def choice_exists(self): + login = self.Get('ur_unix_login') + if login: + exists_groups = self.Get('ur_unix_groups_exists') + return (x for x in self.ldap_group_list() + if x[0] in exists_groups) + return [] + + def check_special(self, value, exists_groups, login): + not_exists = [x for x in value if x not in exists_groups] + if not_exists: + raise VariableError( + _("User {user} is not exist in groups {groups}").format( + groups=", ".join(not_exists), user=login)) + + +class VariableUrUnixSkel(Variable): + """ + Skel директория + """ + opt = ("-k", "--skel") + metavalue = "SKEL_DIR" + value = "/etc/skel" + + def init(self): + self.label = _("Skeleton directory") + self.help = _("set skeletion directory for new account") + + +class VariableUrUnixCreateHomeSet(Variable): + """ + Создавать домашнюю директорию пользователю + """ + type = "bool" + opt = ("-m", "--create-home") + value = "off" + check_after = ["ur_unix_home_path"] + + def init(self): + self.label = _("Create home directory") + self.help = _("create the user's home directory") + + def check_on(self): + home_path = self.Get('ur_unix_home_path') + if path.exists(home_path): + raise VariableError( + _("Home directory %s already exists") % home_path) + + +class VariableUrUnixPw(Variable): + """ + Пароль пользователя + """ + type = "password" + opt = ("-p", "--password") + value = "" + untrusted = True + metavalue = "PASSWORD" + + def init(self): + self.label = _("Password") + self.help = _("set user password") + + def check(self, value): + delete_pw = self.GetBool('ur_unix_pw_delete_set') + change_lock = (self.GetBool('ur_unix_lock_set') != + self.GetBool('ur_unix_lock_exists_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")) + + +class VariableUrUnixPwSet(UnixActionHelper, UnixUserHelper, ReadonlyVariable): + """ + Указан ли пароль у пользователя + """ + type = "bool" + + def init(self): + self.label = _("Password") + + def get_exists(self): + username = self.Get('ur_unix_login') + pw = self.get_password_hash(username) + if pw and pw != self.DeletedPassword: + return "on" + else: + return "off" + + +class VariableUrUnixPwDeleteSet(Variable): + """ + Удалить пароль пользователя + """ + type = "bool" + value = "off" + + opt = ("-d", "--delete") + + def init(self): + self.label = _("Remove user password") + self.help = _("delete the password for the named account") + + +class VariableUrUnixHash(HashHelper, ReadonlyVariable): + """ + Хэш пароля + """ + source = "unix.ur_unix_pw" + + +class VariableUrUnixUserObject(UnixUserHelper, UnixActionHelper, + ReadonlyVariable): + """ + Объект данных пользователя + """ + + def get_exists(self): + login = self.Get('ur_unix_login') + if login: + return self.search_ldap_user_name(login) or "" + return "" + + +class VariableUrUnixShell(ExistsUserHelper, UnixActionHelper, Variable): + """ + Командная оболочка по умолчанию для пользователя + """ + attribute = "shell" + opt = ("-s", "--shell") + metavalue = "SHELL" + + def init(self): + self.label = _("Shell") + self.help = _("login shell of the account") + + def get_new(self): + return "/bin/bash" + + +class VariableUrUnixVisibleSet(ExistsUserHelper, UnixActionHelper, Variable): + """ + Виден ли пользователь + """ + attribute = "visible" + type = "bool" + opt = ("-v", "--visible") + + def init(self): + self.label = _("Visible") + self.help = _("set visible of the account") + + def get_new(self): + return "on" + + +class VariableUrUnixLockSet(ExistsUserHelper, UnixActionHelper, Variable): + """ + Виден ли пользователь + """ + attribute = "lock" + type = "bool" + opt = ("-l", "--lock") + value = "off" + + def init(self): + self.label = _("Locked") + self.help = _("lock the account") + + +class VariableUrUnixLockExistsSet(ExistsUserHelper, UnixActionHelper, Variable): + """ + Виден ли пользователь + """ + type = "bool" + attribute = "lock" + value = "off" + + +class VariableUrUnixVisibleFlag(UnixUserHelper, ReadonlyVariable): + """ + Значение используемое для шаблона + """ + + def get(self): + return self.visible_to_flag(self.GetBool('ur_unix_visible_set')) + + +class VariableUrUnixLockFlag(UnixUserHelper, ReadonlyVariable): + """ + Значение используемое для шаблона + """ + + def get(self): + return self.lock_to_flag(self.GetBool('ur_unix_lock_set')) + + +class VariableUrUnixNextUid(LdapMaxHelper, ReadonlyVariable): + """ + Следующий свободный Uid + """ + base_dn = "{ld_unix_users_dn}" + search_filter = "uid=*" + attr = "uidNumber" + + def get(self): + value = self.get_max() + if value is None: + return self.Get('ur_unix_min_uid') + else: + return str(value + 1) + + +class VariableUrUnixNextGid(LdapMaxHelper, ReadonlyVariable): + """ + Следующий свободный Uid + """ + base_dn = "{ld_unix_groups_dn}" + search_filter = "cn=*" + attr = "gidNumber" + + def get(self): + value = self.get_max() + if value is None: + return self.Get('ur_unix_min_gid') + else: + return str(value + 1) + + +class VariableUrUnixMinUid(Variable): + """ + Минимальный uid + """ + type = "int" + value = "10000" + + +class VariableUrUnixMinGid(Variable): + """ + Минимальный uid + """ + type = "int" + value = "10000" + + +class VariableUrUnixGroupUsers(UnixGroupHelper, ReadonlyVariable): + """ + Текущий список пользователей в группе + """ + type = "list" + + def init(self): + self.label = _("Users") + + def get(self): + group_name = self.Get('ur_unix_group_name') + if group_name: + group = self.search_ldap_group_name(group_name) + if group: + return group.user_list + return [] + + +class VariableUrUnixGroupUsersAdd(UnixUserHelper, Variable): + """ + Пользователи добавляемые в группу + """ + type = "choiceedit-list" + opt = ("-a", "--add") + value = [] + metavalue = "USERS" + + def init(self): + self.label = _("Include in group") + self.help = _("add members") + + def choice(self): + if self.Get('ur_unix_group_name'): + exists_users = self.Get('ur_unix_group_users') + return (x for x in self.ldap_user_list() if + x[0] not in exists_users) + return [] + + def get(self): + exists_users = set(self.Get('ur_unix_group_users')) + replace_users = set(self.Get('ur_unix_group_users_replace')) + return sorted(list(replace_users - exists_users)) + + def check(self, value): + exists_users = self.Get('ur_unix_group_users') + replace_users = self.Get('ur_unix_group_users_replace') + if set(exists_users) != set(replace_users): + raise VariableError(_( + "Appending users to group unavailable " + "with the replace user using")) + group = self.Get('ur_unix_group_name') + users = self.ldap_user_names() + failed = [x for x in value if x not in users] + if failed: + raise VariableError( + _("Wrong users {users}").format( + users=", ".join(failed))) + already_exists = [x for x in value if x in exists_users] + if already_exists: + raise VariableError( + _("Users {users} already exist in group {group}").format( + users=", ".join(already_exists), group=group)) + + +class VariableUrUnixGroupUsersReplace(UnixUserHelper, UnixActionHelper, + Variable): + """ + Замена всех пользователей в группе + """ + type = "choiceedit-list" + opt = ("-U ", "--users") + value = [] + metavalue = "USERS" + + def init(self): + self.label = _("Users") + self.help = _("new user list of group") + + def get_exists(self): + return list(sorted(self.Get('ur_unix_group_users'))) + + def choice_exists(self): + return self.ldap_user_list() + + def check_exists(self, value): + users = self.ldap_user_names() + failed = [x for x in value if x not in users] + if failed: + raise VariableError( + _("Wrong users {users}").format( + users=", ".join(failed))) + + +class VariableUrUnixGroupUsersDel(UnixUserHelper, Variable): + """ + Пользователи добавляемые в группу + """ + type = "choiceedit-list" + opt = ("-r", "--remove") + value = [] + metavalue = "USERS" + + def init(self): + self.label = _("Exclude from groups") + self.help = _("remove members") + + def choice(self): + exists_users = self.Get('ur_unix_group_users') + return (x for x in self.ldap_user_list() if + x[0] in exists_users) + + def get(self): + exists_users = set(self.Get('ur_unix_group_users')) + replace_users = set(self.Get('ur_unix_group_users_replace')) + return sorted(list(exists_users - replace_users)) + + def check(self, value): + exists_users = self.Get('ur_unix_group_users') + replace_users = self.Get('ur_unix_group_users_replace') + if set(exists_users) != set(replace_users): + raise VariableError(_( + "Removing users from group unavailable " + "with the replace user using")) + if not exists_users and value: + raise VariableError(_("Group has not members")) + + group = self.Get('ur_unix_group_name') + users = self.ldap_user_names() + failed = [x for x in value if x not in users] + if failed: + raise VariableError( + _("Wrong users {users}").format( + users=", ".join(failed))) + not_exists = [x for x in value if x not in exists_users] + if not_exists: + raise VariableError( + _("Users {users} are not exist in group {group}").format( + users=", ".join(not_exists), group=group)) + + def humanReadable(self): + if not self.Get(): + return _("Not change") + + +class VariableUrUnixGroupNewname(UnixGroupHelper, Variable): + opt = ("-n", "--new-name") + value = "" + metavalue = "NEW_GROUP" + + def init(self): + self.label = _("Group name") + self.help = _("use NEW_GROUP name by GROUP") + + def get(self): + return self.Get('ur_unix_group_name') + + def check(self, value): + if value == self.Get('ur_unix_group_name'): + return + #raise VariableError(_("The new group name is the same as the old")) + if self.search_ldap_group_name(value): + raise VariableError( + _("Group {name} already exists").format(name=value)) + + def humanReadable(self): + value = self.Get() + if not value: + return _("Not change") + 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 VariableUrUnixUserShow(UnixUserHelper, UnixActionHelper, Variable): + """ + Группа + """ + type = "choice" + opt = ["-U", "--user"] + metavalue = "USER" + + def init(self): + self.label = _("login") + self.help = _("show user") + + def get(self): + return "all" + + def choice_exists(self): + try: + return ([("all", _("All"))] + + self.ldap_user_list()) + except LDAPConnectError as s: + raise VariableError(str(s)) + + +class VariableUrUnixUserCount(UnixUserHelper, UnixActionHelper, + ReadonlyVariable): + """ + Количество пользователей + """ + type = "int" + + def get_exists(self): + return len(self.ldap_user_list()) + + +class VariableClUnixGroupAliases(ReadonlyVariable): + """ + Алиасы для переменных + """ + type = "table" + value = [('name', 'ur_unix_group_name'), + ('id', 'ur_unix_group_id'), + ('comment', 'ur_unix_group_comment'), + ('users', 'ur_unix_group_users')] + + +class VariableClUnixGroupFields(Variable): + """ + Список полей для вывода данных группы + """ + type = "choice-list" + element = "selecttable" + opt = ["--fields"] + metavalue = "FIELDS" + + def init(self): + self.label = _("Fields") + self.help = _("fields for display") + + def choice(self): + data = self.Get('cl_unix_group_aliases') + return [(x, self.parent.getInfo(y).label) for x, y in data] + + def get(self): + return [x for x, y in self.Get('cl_unix_group_aliases')] + + +class VariableClUnixGroupShowFields(ReadonlyVariable): + """ + Список переменных полей при отображении списка групп + """ + type = "list" + + def get(self): + mapping = dict(self.Get('cl_unix_group_aliases')) + return [mapping[x] for x in self.Get('cl_unix_group_fields')] + + +class VariableClUnixUserAliases(ReadonlyVariable): + """ + Алиасы для переменных + """ + type = "table" + value = [ + ('login', 'ur_unix_login'), + ('uid', 'ur_unix_uid'), + ('gid', 'ur_unix_primary_group'), + ('comment', 'ur_unix_comment'), + ('lock', 'ur_unix_lock_set'), + ('visible', 'ur_unix_visible_set'), + ('groups', 'ur_unix_groups'), + ('home', 'ur_unix_home_path'), + ('shell', 'ur_unix_shell'), + ('password', 'ur_unix_pw_set'), + ] + + +class VariableClUnixUserFields(FieldsHelper, Variable): + """ + Список полей для вывода данных группы + """ + alias_variable = "cl_unix_user_aliases" + + +class VariableClUnixUserShowFields(ShowFieldsHelper, ReadonlyVariable): + """ + Список переменных полей при отображении списка групп + """ + alias_variable = "cl_unix_user_aliases" + source_variable = "cl_unix_user_fields" diff --git a/pym/unix/wsdl_unix.py b/pym/unix/wsdl_unix.py index d888b4a..a5a58b1 100644 --- a/pym/unix/wsdl_unix.py +++ b/pym/unix/wsdl_unix.py @@ -21,8 +21,20 @@ from calculate.lib.datavars import VariableError, DataVarsError from calculate.core.server.func import WsdlBase from .unix import Unix, UnixError from calculate.ldap.ldap import LdapError +from calculate.unix.variables.action import Actions +from calculate.server.server import Server from calculate.server.variables.action import Actions as ServerActions from utils.cl_unix_setup import ClUnixSetupAction +from utils.cl_unix_useradd import ClUnixUseraddAction +from utils.cl_unix_usermod import ClUnixUsermodAction +from utils.cl_unix_userdel import ClUnixUserdelAction +from utils.cl_unix_passwd import ClUnixPasswdAction +from utils.cl_unix_groupadd import ClUnixGroupaddAction +from utils.cl_unix_groupmod import ClUnixGroupmodAction +from utils.cl_unix_groupdel import ClUnixGroupdelAction +from utils.cl_unix_groupshow import ClUnixGroupshowAction +from utils.cl_unix_usershow import ClUnixUsershowAction +from calculate.ldap.ldap import Ldap _ = lambda x: x from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate @@ -40,11 +52,11 @@ class Wsdl(WsdlBase): # идентификатор метода 'method_name': Unix.Method.Setup, # категория метода - 'category': __('Unix'), + 'category': __('Setup Server'), # заголовок метода - 'title': __("Setup"), + 'title': __("Unix Accounts"), # иконка для графической консоли - 'image': 'setup', + 'image': 'preferences-system-login', # метод присутствует в графической консоли 'gui': True, # консольная команда @@ -52,28 +64,582 @@ class Wsdl(WsdlBase): # права для запуска метода 'rights': ['unix'], # объект содержащий модули для действия - 'logic': {'Unix': Unix}, + 'logic': {'Unix': Unix, + 'Server': Server}, # описание действия 'action': ClUnixSetupAction, # объект переменных 'datavars': "unix", - 'native_error': (VariableError, DataVarsError, LdapError, UnixError), + 'native_error': ( + VariableError, DataVarsError, LdapError, UnixError), # значения по умолчанию для переменных этого метода 'setvars': {'cl_action!': ServerActions.Setup, - 'server.cl_server_name!': "unix", + 'server.cl_server_name': Unix.service_name, + 'cl_unix_action': Actions.Setup, 'cl_autoupdate_set': 'on' - # 'cl_dispatch_conf_default': "usenew" + # 'cl_dispatch_conf_default': "usenew" }, # описание груп (список лямбда функций) 'groups': [ lambda group: group( _("Unix server"), - brief=('ldap.ld_base_dn',), + brief=( + 'ldap.ld_base_dn', + 'server.sr_ldap_set', + 'server.sr_unix_set', + ), hide=(), - normal=(), - expert=()), - ], - 'brief': {'next': __("Perform"), - 'name': __("Setup Unix"),} + expert=(), + ), + ], + 'depends': [Ldap.Method.Setup], + 'brief': {'next': __("Perform"), + 'name': __("Setup Unix"), } + }, + # + # Добавить пользователя + # + { + # идентификатор метода + 'method_name': Unix.Method.UserAdd, + # категория метода + 'category': __('Old Unix'), + # заголовок метода + 'title': __("Add the User"), + # иконка для графической консоли + 'image': 'setup', + # метод присутствует в графической консоли + 'gui': False, + # консольная команда + 'command': 'cl-unix-useradd', + # права для запуска метода + 'rights': ['unix'], + # объект содержащий модули для действия + 'logic': {'Unix': Unix, + 'Server': Server}, + # описание действия + 'action': ClUnixUseraddAction, + # объект переменных + 'datavars': "unix", + 'native_error': ( + VariableError, DataVarsError, LdapError, UnixError), + # значения по умолчанию для переменных этого метода + 'setvars': {'cl_action!': ServerActions.Setup, + 'server.cl_server_name': Unix.service_name, + 'cl_unix_action': Actions.UserAdd, + 'cl_autoupdate_set': 'on', + 'ldap.cl_ldap_bind_dn!': '{ld_unix_dn}', + 'ldap.cl_ldap_bind_pw!': '{ld_unix_pw}', + # 'cl_dispatch_conf_default': "usenew" + }, + # описание груп (список лямбда функций) + 'groups': [ + lambda group: group( + _("User"), + brief=('ur_unix_login',), + normal=( + 'ur_unix_login', + 'ur_unix_pw', + 'ur_unix_comment', + 'ur_unix_primary_group', + 'ur_unix_groups', + ), + expert=( + 'ur_unix_uid', + 'ur_unix_home_path', + 'ur_unix_shell', + 'ur_unix_create_home_set', + 'ur_unix_visible_set', + 'ur_unix_skel', + ), + next_label=_("Perform") + ), + ], + }, + # + # Добавить группу + # + { + # идентификатор метода + 'method_name': Unix.Method.GroupAdd, + # категория метода + 'category': __('Old Unix'), + # заголовок метода + 'title': __("Add the Group"), + # иконка для графической консоли + 'image': 'setup', + # метод присутствует в графической консоли + 'gui': False, + # консольная команда + 'command': 'cl-unix-groupadd', + # права для запуска метода + 'rights': ['unix'], + # объект содержащий модули для действия + 'logic': {'Unix': Unix, + 'Server': Server}, + # описание действия + 'action': ClUnixGroupaddAction, + # объект переменных + 'datavars': "unix", + 'native_error': ( + VariableError, DataVarsError, LdapError, UnixError), + # значения по умолчанию для переменных этого метода + 'setvars': {'cl_action!': ServerActions.Setup, + 'server.cl_server_name': Unix.service_name, + 'cl_unix_action': Actions.GroupAdd, + 'cl_autoupdate_set': 'on', + 'ldap.cl_ldap_bind_dn!': '{ld_unix_dn}', + 'ldap.cl_ldap_bind_pw!': '{ld_unix_pw}', + # 'cl_dispatch_conf_default': "usenew" + }, + # описание груп (список лямбда функций) + 'groups': [ + lambda group: group( + _("Add the New Group"), + brief=(), + hide=('ur_unix_base_dir',), + normal=( + 'ur_unix_group_name', + 'ur_unix_group_id', + 'ur_unix_group_comment', + ), + expert=(), + next_label=_("Perform") + ), + ], + }, + # + # Изменить параметры группы + # + { + # идентификатор метода + 'method_name': Unix.Method.GroupMod, + # категория метода + 'category': __('Old Unix'), + # заголовок метода + 'title': __("Modify the Group"), + # иконка для графической консоли + 'image': 'setup', + # метод присутствует в графической консоли + 'gui': False, + # консольная команда + 'command': 'cl-unix-groupmod', + # права для запуска метода + 'rights': ['unix'], + # объект содержащий модули для действия + 'logic': {'Unix': Unix, + 'Server': Server}, + # описание действия + 'action': ClUnixGroupmodAction, + # объект переменных + 'datavars': "unix", + 'native_error': ( + VariableError, DataVarsError, LdapError, UnixError), + # значения по умолчанию для переменных этого метода + 'setvars': {'cl_action!': ServerActions.Setup, + 'server.cl_server_name': Unix.service_name, + 'cl_unix_action': Actions.GroupMod, + 'cl_autoupdate_set': 'on', + 'ldap.cl_ldap_bind_dn!': '{ld_unix_dn}', + 'ldap.cl_ldap_bind_pw!': '{ld_unix_pw}', + # 'cl_dispatch_conf_default': "usenew" + }, + # описание груп (список лямбда функций) + 'groups': [ + lambda group: group( + _("Group"), + brief=('ur_unix_group_name_exists',), + normal=( + 'ur_unix_group_name_exists', + 'ur_unix_group_newname', + 'ur_unix_group_id', + 'ur_unix_group_comment', + 'ur_unix_group_users_replace', + ), + hide=('ur_unix_group_users_replace',), + expert=( + 'ur_unix_group_users_add', + 'ur_unix_group_users_del', + ), + custom_buttons=[ + ('but0', _("Back"), + Unix.Method.GroupShow, + "button"), + ('but1', _("Delete"), + Unix.Method.GroupDel, + "button",), + ('but2', _("Modify"), + Unix.Method.GroupMod, "button"), + ] + ), + ], + 'invalidators': { + 'ur_unix_group_name_exists': ( + 'ur_unix_group_id', + 'ur_unix_group_comment', + 'ur_unix_group_newname', + 'ur_unix_group_users_replace', + 'ur_unix_group_users_add', + 'ur_unix_group_users_del',) + }, + 'brief': {'next': __("Perform"), + 'name': __("Modify the Unix Group"), } + }, + # + # Удалить группу + # + { + # идентификатор метода + 'method_name': Unix.Method.GroupDel, + # категория метода + 'category': __('Old Unix'), + # заголовок метода + 'title': __("Delete the Group"), + # иконка для графической консоли + 'image': 'setup', + # метод присутствует в графической консоли + 'gui': False, + # консольная команда + 'command': 'cl-unix-groupdel', + # права для запуска метода + 'rights': ['unix'], + # объект содержащий модули для действия + 'logic': {'Unix': Unix, + 'Server': Server}, + # описание действия + 'action': ClUnixGroupdelAction, + # объект переменных + 'datavars': "unix", + 'native_error': ( + VariableError, DataVarsError, LdapError, UnixError), + # значения по умолчанию для переменных этого метода + 'setvars': {'cl_action!': ServerActions.Setup, + 'server.cl_server_name': Unix.service_name, + 'cl_unix_action': Actions.GroupDel, + 'cl_autoupdate_set': 'on', + 'ldap.cl_ldap_bind_dn!': '{ld_unix_dn}', + 'ldap.cl_ldap_bind_pw!': '{ld_unix_pw}', + # 'cl_dispatch_conf_default': "usenew" + }, + # описание груп (список лямбда функций) + 'groups': [ + lambda group: group( + _("Group"), + brief=(), + normal=( + 'ur_unix_group_name_exists', + ), + next_label=_("Perform") + ), + ], + }, + # + # Изменить параметры пользователя + # + { + # идентификатор метода + 'method_name': Unix.Method.UserMod, + # категория метода + 'category': __('Old Unix'), + # заголовок метода + 'title': __("Modify the User"), + # иконка для графической консоли + 'image': 'setup', + # метод присутствует в графической консоли + 'gui': False, + # консольная команда + 'command': 'cl-unix-usermod', + # права для запуска метода + 'rights': ['unix'], + # объект содержащий модули для действия + 'logic': {'Unix': Unix, + 'Server': Server}, + # описание действия + 'action': ClUnixUsermodAction, + # объект переменных + 'datavars': "unix", + 'native_error': ( + VariableError, DataVarsError, LdapError, UnixError), + # значения по умолчанию для переменных этого метода + 'setvars': {'cl_action!': ServerActions.Setup, + 'server.cl_server_name': Unix.service_name, + 'cl_unix_action': Actions.UserMod, + 'cl_autoupdate_set': 'on', + 'ldap.cl_ldap_bind_dn!': '{ld_unix_dn}', + 'ldap.cl_ldap_bind_pw!': '{ld_unix_pw}', + # 'cl_dispatch_conf_default': "usenew" + }, + # описание груп (список лямбда функций) + 'groups': [ + lambda group: group( + _("User"), + normal=( + 'ur_unix_login_exists', + 'ur_unix_pw', + 'ur_unix_primary_group', + 'ur_unix_comment', + 'ur_unix_groups', + 'ur_unix_visible_set', + 'ur_unix_lock_set', + ), + expert=( + 'ur_unix_groups_add', + 'ur_unix_groups_del', + 'ur_unix_home_path', + 'ur_unix_home_path_move', + 'ur_unix_shell', + 'ur_unix_pw_delete_set', + ), + custom_buttons=[ + ('but0', _("Back"), + Unix.Method.UserShow, + "button"), + ('but1', _("Delete"), + Unix.Method.UserDel, + "button",), + ('but2', _("Modify"), + Unix.Method.UserMod, "button"), + ], + next_label=_("Perform") + ), + ], + 'invalidators': { + 'ur_unix_login_exists': ( + 'ur_unix_primary_group', + 'ur_unix_comment', + 'ur_unix_groups', + 'ur_unix_visible_set', + 'ur_unix_lock_set', + 'ur_unix_groups_add', + 'ur_unix_groups_del', + 'ur_unix_home_path', + 'ur_unix_home_path_move', + 'ur_unix_shell', + 'ur_unix_pw_delete_set', + ) }, + }, + # + # Удалить пользователя + # + { + # идентификатор метода + 'method_name': Unix.Method.UserDel, + # категория метода + 'category': __('Old Unix'), + # заголовок метода + 'title': __("Delete the User"), + # иконка для графической консоли + 'image': 'setup', + # метод присутствует в графической консоли + 'gui': False, + # консольная команда + 'command': 'cl-unix-userdel', + # права для запуска метода + 'rights': ['unix'], + # объект содержащий модули для действия + 'logic': {'Unix': Unix, + 'Server': Server}, + # описание действия + 'action': ClUnixUserdelAction, + # объект переменных + 'datavars': "unix", + 'native_error': ( + VariableError, DataVarsError, LdapError, UnixError), + # значения по умолчанию для переменных этого метода + 'setvars': {'cl_action!': ServerActions.Setup, + 'server.cl_server_name': Unix.service_name, + 'cl_unix_action': Actions.UserDel, + 'cl_autoupdate_set': 'on', + 'ldap.cl_ldap_bind_dn!': '{ld_unix_dn}', + 'ldap.cl_ldap_bind_pw!': '{ld_unix_pw}', + # 'cl_dispatch_conf_default': "usenew" + }, + # описание груп (список лямбда функций) + 'groups': [ + lambda group: group( + _("User"), + brief=(), + normal=( + 'ur_unix_login_exists', + ), + next_label=_("Perform") + ), + ], + }, + # + # Сменить пароль пользователю + # + { + # идентификатор метода + 'method_name': Unix.Method.Passwd, + # категория метода + 'category': __('Old Unix'), + # заголовок метода + 'title': __("Change the Password"), + # иконка для графической консоли + 'image': 'setup', + # метод присутствует в графической консоли + 'gui': False, + # консольная команда + 'command': 'cl-unix-passwd', + # права для запуска метода + 'rights': ['unix'], + # объект содержащий модули для действия + 'logic': {'Unix': Unix, + 'Server': Server}, + # описание действия + 'action': ClUnixPasswdAction, + # объект переменных + 'datavars': "unix", + 'native_error': ( + VariableError, DataVarsError, LdapError, UnixError), + # значения по умолчанию для переменных этого метода + 'setvars': {'cl_action!': ServerActions.Setup, + 'server.cl_server_name': Unix.service_name, + 'cl_unix_action': Actions.Passwd, + 'cl_autoupdate_set': 'on', + 'ldap.cl_ldap_bind_dn!': '{ld_unix_dn}', + 'ldap.cl_ldap_bind_pw!': '{ld_unix_pw}', + # 'cl_dispatch_conf_default': "usenew" + }, + # описание груп (список лямбда функций) + 'groups': [ + lambda group: group( + _("User"), + brief=(), + normal=( + 'ur_unix_login_exists', + 'ur_unix_pw', + 'ur_unix_pw_delete_set', + 'ur_unix_lock_set' + ), + next_label=_("Perform") + ), + ], + }, + # + # Просмотр групп + # + { + # идентификатор метода + 'method_name': Unix.Method.GroupShow, + # категория метода + 'category': __('Server'), + # заголовок метода + 'title': __("Unix Groups"), + # иконка для графической консоли + 'image': 'group', + # метод присутствует в графической консоли + 'gui': lambda Get: Get('server.sr_unix_set') == 'on', + # консольная команда + 'command': 'cl-unix-groupshow', + # права для запуска метода + 'rights': ['unix'], + # объект содержащий модули для действия + 'logic': {'Unix': Unix, + 'Server': Server}, + # описание действия + 'action': ClUnixGroupshowAction, + # объект переменных + 'datavars': "unix", + 'native_error': ( + VariableError, DataVarsError, LdapError, UnixError), + # значения по умолчанию для переменных этого метода + 'setvars': {'cl_action!': ServerActions.Setup, + 'server.cl_server_name': Unix.service_name, + 'cl_unix_action': Actions.GroupShow, + 'cl_autoupdate_set': 'on', + 'core.cl_page_max!': '{ur_unix_group_count}', + 'ldap.cl_ldap_bind_dn!': '{ld_unix_dn}', + 'ldap.cl_ldap_bind_pw!': '{ld_unix_pw}', + # 'cl_dispatch_conf_default': "usenew" + }, + # описание груп (список лямбда функций) + 'groups': [ + lambda group: group( + _("Groups"), + brief=(), + next_label=_("Show"), + normal=( + 'ur_unix_group_show', + 'core.cl_page_count', 'core.cl_page_offset', + ), + expert=( + 'cl_unix_group_fields', + ), + custom_buttons=[ + ('but0', _("Add Group"), + Unix.Method.GroupAdd, + "button_view"), + ('but1', _("Show"), + Unix.Method.GroupShow, + "button"), + ] + ), + ], + 'depends': [Unix.Method.Setup] + }, + # + # Просмотр пользователей + # + { + # идентификатор метода + 'method_name': Unix.Method.UserShow, + # категория метода + 'category': __('Server'), + # заголовок метода + 'title': __("Unix Users"), + # иконка для графической консоли + 'image': 'user', + # метод присутствует в графической консоли + 'gui': lambda Get: Get('server.sr_unix_set') == 'on', + # консольная команда + 'command': 'cl-unix-usershow', + # права для запуска метода + 'rights': ['unix'], + # объект содержащий модули для действия + 'logic': {'Unix': Unix, + 'Server': Server}, + # описание действия + 'action': ClUnixUsershowAction, + # объект переменных + 'datavars': "unix", + 'native_error': ( + VariableError, DataVarsError, LdapError, UnixError), + # значения по умолчанию для переменных этого метода + 'setvars': {'cl_action!': ServerActions.Setup, + 'server.cl_server_name': Unix.service_name, + 'cl_unix_action': Actions.UserShow, + 'cl_autoupdate_set': 'on', + 'core.cl_page_max!': '{ur_unix_user_count}', + 'ldap.cl_ldap_bind_dn!': '{ld_unix_dn}', + 'ldap.cl_ldap_bind_pw!': '{ld_unix_pw}', + # 'cl_dispatch_conf_default': "usenew" + }, + # описание груп (список лямбда функций) + 'groups': [ + lambda group: group( + _("Users"), + brief=(), + next_label=_("Show"), + normal=( + 'ur_unix_user_show', + 'core.cl_page_count', 'core.cl_page_offset', + ), + expert=( + 'cl_unix_user_fields', + ), + custom_buttons=[ + ('but0', _("Add User"), + Unix.Method.UserAdd, + "button_view"), + ('but1', _("Show"), + Unix.Method.UserShow, + "button"), + ] + ), + ], + 'depends': [Unix.Method.Setup] + }, ]