def GET(self, profile_type, domain): i = web.input() self.domain = web.safestr(domain.split('/', 1)[0]) self.profile_type = web.safestr(profile_type) if not iredutils.isDomain(self.domain): return web.seeother('/domains?msg=EMPTY_DOMAIN') domainLib = domainlib.Domain() result = domainLib.profile(domain=self.domain) if result[0] is True: r = domainLib.listAccounts(attrs=['domainName']) if r[0] is True: allDomains = r[1] else: return r allAccountSettings = ldaputils.getAccountSettingFromLdapQueryResult( result[1], key='domainName', ) return web.render( 'ldap/domain/profile.html', cur_domain=self.domain, allDomains=allDomains, allAccountSettings=allAccountSettings, profile=result[1], profile_type=self.profile_type, msg=i.get('msg', None), ) else: return web.seeother('/domains?msg=' + result[1])
def getDomainDefaultUserQuota(self, domain, domainAccountSetting=None,): # Return 0 as unlimited. self.domain = web.safestr(domain) self.dn = ldaputils.convKeywordToDN(self.domain, accountType='domain') if domainAccountSetting is not None: if 'defaultQuota' in domainAccountSetting.keys(): return int(domainAccountSetting['defaultQuota']) else: return 0 else: try: result = self.conn.search_s( self.dn, ldap.SCOPE_BASE, '(domainName=%s)' % self.domain, ['domainName', 'accountSetting'], ) settings = ldaputils.getAccountSettingFromLdapQueryResult(result, key='domainName',) if 'defaultQuota' in settings[self.domain].keys(): return int(settings[self.domain]['defaultQuota']) else: return 0 except Exception, e: return 0
def GET(self, profile_type, domain): i = web.input() self.domain = web.safestr(domain.split('/', 1)[0]) self.profile_type = web.safestr(profile_type) if not iredutils.isDomain(self.domain): return web.seeother('/domains?msg=EMPTY_DOMAIN') domainLib = domainlib.Domain() result = domainLib.profile(domain=self.domain) if result[0] is True: r = domainLib.listAccounts(attrs=['domainName']) if r[0] is True: allDomains = r[1] else: return r allAccountSettings = ldaputils.getAccountSettingFromLdapQueryResult(result[1], key='domainName',) return web.render( 'ldap/domain/profile.html', cur_domain=self.domain, allDomains=allDomains, allAccountSettings=allAccountSettings, profile=result[1], profile_type=self.profile_type, msg=i.get('msg', None), ) else: return web.seeother('/domains?msg=' + result[1])
def GET(self, cur_page=1): i = web.input() cur_page = int(cur_page) if cur_page == 0: cur_page == 1 domainLib = domainlib.Domain() result = domainLib.listAccounts() if result[0] is True: allDomains = result[1] # Get value of accountSetting. allAccountSettings = ldaputils.getAccountSettingFromLdapQueryResult(allDomains, key='domainName',) else: return result connutils = connUtils.Utils() sl = connutils.getSizelimitFromAccountLists(allDomains, curPage=cur_page, sizelimit=session.get('pageSizeLimit', 50),) if cur_page > sl.get('totalPages'): cur_page = sl.get('totalPages') return web.render( 'ldap/domain/list.html', cur_page=cur_page, total=sl.get('totalAccounts'), allDomains=sl.get('accountList'), allAccountSettings=allAccountSettings, msg=i.get('msg', None), )
def getDomainDefaultUserQuota(self, domain, domainAccountSetting=None,): # Return 0 as unlimited. self.domain = web.safestr(domain) self.dn = ldaputils.convert_keyword_to_dn(self.domain, accountType='domain') if self.dn[0] is False: return self.dn if domainAccountSetting is not None: if 'defaultQuota' in domainAccountSetting.keys(): return int(domainAccountSetting['defaultQuota']) else: return 0 else: try: result = self.conn.search_s( self.dn, ldap.SCOPE_BASE, '(domainName=%s)' % self.domain, ['domainName', 'accountSetting'], ) settings = ldaputils.getAccountSettingFromLdapQueryResult(result, key='domainName',) if 'defaultQuota' in settings[self.domain].keys(): return int(settings[self.domain]['defaultQuota']) else: return 0 except Exception: return 0
def GET(self, domainName=None): i = web.input() if domainName is None: self.cur_domain = '' else: self.cur_domain = web.safestr(domainName) domainLib = domainlib.Domain() result = domainLib.listAccounts(attrs=['domainName', 'accountSetting', 'domainCurrentQuotaSize',]) if result[0] is True: allDomains = result[1] if len(allDomains) == 0: return web.seeother('/domains?msg=NO_DOMAIN_AVAILABLE') else: # Redirect to create new user under first domain, so that we # can get per-domain account settings, such as number of # account limit, password length control, etc. if self.cur_domain == '': return web.seeother('/create/user/' + str(allDomains[0][1]['domainName'][0])) # Get accountSetting of current domain. allAccountSettings = ldaputils.getAccountSettingFromLdapQueryResult(allDomains, key='domainName') domainAccountSetting = allAccountSettings.get(self.cur_domain, {}) defaultUserQuota = domainLib.getDomainDefaultUserQuota(self.cur_domain, domainAccountSetting) else: return web.seeother('/domains?msg=' % result[1]) # Get number of account limit. connutils = connUtils.Utils() result = connutils.getNumberOfCurrentAccountsUnderDomain(self.cur_domain, accountType='user', ) if result[0] is True: numberOfCurrentAccounts = result[1] else: numberOfCurrentAccounts = 0 # Get current domain quota size. result = connutils.getDomainCurrentQuotaSizeFromLDAP(domain=self.cur_domain) if result[0] is True: domainCurrentQuotaSize = result[1] else: # -1 means temporary error. Don't allow to create new user. domainCurrentQuotaSize = -1 return web.render('ldap/user/create.html', cur_domain=self.cur_domain, allDomains=allDomains, defaultUserQuota=defaultUserQuota, domainAccountSetting=domainAccountSetting, numberOfCurrentAccounts=numberOfCurrentAccounts, domainCurrentQuotaSize=domainCurrentQuotaSize, msg=i.get('msg'), )
def getDomainAccountSetting(self, domain,): result = self.getAllDomains( filter='(&(objectClass=mailDomain)(domainName=%s))' % domain, attrs=['domainName', 'accountSetting',], ) if result[0] is True: allDomains = result[1] else: return result # Get accountSetting of current domain. try: allAccountSettings = ldaputils.getAccountSettingFromLdapQueryResult(allDomains, key='domainName') return (True, allAccountSettings.get(domain, {})) except Exception, e: return (False, ldaputils.getExceptionDesc(e))
def getDomainAccountSetting(self, domain,): result = self.getAllDomains( filter='(&(objectClass=mailDomain)(domainName=%s))' % domain, attrs=['domainName', 'accountSetting', ], ) if result[0] is True: allDomains = result[1] else: return result # Get accountSetting of current domain. try: allAccountSettings = ldaputils.getAccountSettingFromLdapQueryResult(allDomains, key='domainName') return (True, allAccountSettings.get(domain, {})) except Exception, e: return (False, ldaputils.getExceptionDesc(e))
def GET(self, cur_page=1): i = web.input() cur_page = int(cur_page) if cur_page == 0: cur_page == 1 domainLib = domainlib.Domain() result = domainLib.listAccounts() if result[0] is True: allDomains = result[1] # Get value of accountSetting. allAccountSettings = ldaputils.getAccountSettingFromLdapQueryResult( allDomains, key='domainName', ) else: return result connutils = connUtils.Utils() sl = connutils.getSizelimitFromAccountLists( allDomains, curPage=cur_page, sizelimit=session.get('pageSizeLimit', 50), ) if cur_page > sl.get('totalPages'): cur_page = sl.get('totalPages') return web.render( 'ldap/domain/list.html', cur_page=cur_page, total=sl.get('totalAccounts'), allDomains=sl.get('accountList'), allAccountSettings=allAccountSettings, msg=i.get('msg', None), )
def GET(self, domainName=None): i = web.input() if domainName is None: self.cur_domain = '' else: self.cur_domain = web.safestr(domainName) domainLib = domainlib.Domain() result = domainLib.listAccounts(attrs=[ 'domainName', 'accountSetting', 'domainCurrentQuotaSize', ]) if result[0] is True: allDomains = result[1] if len(allDomains) == 0: raise web.seeother('/domains?msg=NO_DOMAIN_AVAILABLE') else: # Redirect to create new user under first domain, so that we # can get per-domain account settings, such as number of # account limit, password length control, etc. if self.cur_domain == '': raise web.seeother('/create/user/' + str(allDomains[0][1]['domainName'][0])) # Get accountSetting of current domain. allAccountSettings = ldaputils.getAccountSettingFromLdapQueryResult( allDomains, key='domainName') domainAccountSetting = allAccountSettings.get(self.cur_domain, {}) defaultUserQuota = domainLib.getDomainDefaultUserQuota( self.cur_domain, domainAccountSetting) else: raise web.seeother('/domains?msg=' % web.urlquote(result[1])) # Get number of account limit. connutils = connUtils.Utils() result = connutils.getNumberOfCurrentAccountsUnderDomain( self.cur_domain, accountType='user', ) if result[0] is True: numberOfCurrentAccounts = result[1] else: numberOfCurrentAccounts = 0 # Get current domain quota size. result = connutils.getDomainCurrentQuotaSizeFromLDAP( domain=self.cur_domain) if result[0] is True: domainCurrentQuotaSize = result[1] else: # -1 means temporary error. Don't allow to create new user. domainCurrentQuotaSize = -1 return web.render('ldap/user/create.html', cur_domain=self.cur_domain, allDomains=allDomains, defaultUserQuota=defaultUserQuota, domainAccountSetting=domainAccountSetting, numberOfCurrentAccounts=numberOfCurrentAccounts, domainCurrentQuotaSize=domainCurrentQuotaSize, msg=i.get('msg'))
def add(self, domain, data): # Get domain name, username, cn. self.domain = web.safestr(data.get('domainName')).strip().lower() self.username = web.safestr(data.get('username')).strip().lower() self.mail = self.username + '@' + self.domain self.groups = data.get('groups', []) if not iredutils.isDomain(self.domain) or not iredutils.isEmail(self.mail): return (False, 'MISSING_DOMAIN_OR_USERNAME') # Check account existing. connutils = connUtils.Utils() if connutils.isAccountExists(domain=self.domain, filter='(mail=%s)' % self.mail): return (False, 'ALREADY_EXISTS') # Get @domainAccountSetting. domainLib = domainlib.Domain() result_domain_profile = domainLib.profile(self.domain) # Initial parameters. domainAccountSetting = {} self.aliasDomains = [] if result_domain_profile[0] is True: domainProfile = result_domain_profile[1] domainAccountSetting = ldaputils.getAccountSettingFromLdapQueryResult(domainProfile, key='domainName').get(self.domain, {}) self.aliasDomains = domainProfile[0][1].get('domainAliasName', []) # Check password. self.newpw = web.safestr(data.get('newpw')) self.confirmpw = web.safestr(data.get('confirmpw')) result = iredutils.verifyNewPasswords(self.newpw, self.confirmpw, min_passwd_length=domainAccountSetting.get('minPasswordLength', '0'), max_passwd_length=domainAccountSetting.get('maxPasswordLength', '0'), ) if result[0] is True: self.passwd = ldaputils.generatePasswd(result[1]) else: return result # Get display name. self.cn = data.get('cn') # Get user quota. Unit is MB. # 0 or empty is not allowed if domain quota is set, set to # @defaultUserQuota or @domainSpareQuotaSize # Initial final mailbox quota. self.quota = 0 # Get mail quota from web form. defaultUserQuota = domainLib.getDomainDefaultUserQuota(self.domain, domainAccountSetting) self.mailQuota = str(data.get('mailQuota')).strip() if self.mailQuota.isdigit(): self.mailQuota = int(self.mailQuota) else: self.mailQuota = defaultUserQuota # 0 means unlimited. domainQuotaSize, domainQuotaUnit = domainAccountSetting.get('domainQuota', '0:GB').split(':') if int(domainQuotaSize) == 0: # Unlimited. self.quota = self.mailQuota else: # Get domain quota, convert to MB. if domainQuotaUnit == 'TB': domainQuota = int(domainQuotaSize) * 1024 * 1024 # TB elif domainQuotaUnit == 'GB': domainQuota = int(domainQuotaSize) * 1024 # GB else: domainQuota = int(domainQuotaSize) # MB # TODO Query whole domain and calculate current quota size, not read from domain profile. #domainCurrentQuotaSize = int(domainProfile[0][1].get('domainCurrentQuotaSize', ['0'])[0]) / (1024*1024) result = connutils.getDomainCurrentQuotaSizeFromLDAP(domain=self.domain) if result[0] is True: domainCurrentQuotaSize = result[1] else: domainCurrentQuotaSize = 0 # Spare quota. domainSpareQuotaSize = domainQuota - domainCurrentQuotaSize/(1024*1024) if domainSpareQuotaSize <= 0: return (False, 'EXCEEDED_DOMAIN_QUOTA_SIZE') # Get FINAL mailbox quota. if self.mailQuota == 0: self.quota = domainSpareQuotaSize else: if domainSpareQuotaSize > self.mailQuota: self.quota = self.mailQuota else: self.quota = domainSpareQuotaSize # Get default groups. self.groups = [ web.safestr(v) for v in domainAccountSetting.get('defaultList', '').split(',') if iredutils.isEmail(v) ] self.defaultStorageBaseDirectory = domainAccountSetting.get('defaultStorageBaseDirectory', None) # Get default mail list which set in domain accountSetting. ldif = iredldif.ldif_mailuser( domain=self.domain, aliasDomains=self.aliasDomains, username=self.username, cn=self.cn, passwd=self.passwd, quota=self.quota, groups=self.groups, storageBaseDirectory=self.defaultStorageBaseDirectory, ) if attrs.RDN_USER == 'mail': self.dn = ldaputils.convKeywordToDN(self.mail, accountType='user') elif attrs.RDN_USER == 'cn': self.dn = 'cn=' + self.cn + ',' + attrs.DN_BETWEEN_USER_AND_DOMAIN + \ ldaputils.convKeywordToDN(self.domain, accountType='domain') elif attrs.RDN_USER == 'uid': self.dn = 'uid=' + self.username + ',' + attrs.DN_BETWEEN_USER_AND_DOMAIN + \ ldaputils.convKeywordToDN(self.domain, accountType='domain') else: return (False, 'UNSUPPORTED_USER_RDN') try: self.conn.add_s(ldap.filter.escape_filter_chars(self.dn), ldif,) web.logger(msg="Create user: %s." % (self.mail), domain=self.domain, event='create',) return (True,) except ldap.ALREADY_EXISTS: return (False, 'ALREADY_EXISTS') except Exception, e: return (False, ldaputils.getExceptionDesc(e))
def add(self, domain, data): # Get domain name, username, cn. self.domain = web.safestr(data.get('domainName')).strip().lower() self.username = web.safestr(data.get('username')).strip().lower() self.mail = self.username + '@' + self.domain self.groups = data.get('groups', []) if not iredutils.isDomain(self.domain) or not iredutils.isEmail( self.mail): return (False, 'MISSING_DOMAIN_OR_USERNAME') # Check account existing. connutils = connUtils.Utils() if connutils.isAccountExists(domain=self.domain, filter='(mail=%s)' % self.mail): return (False, 'ALREADY_EXISTS') # Get @domainAccountSetting. domainLib = domainlib.Domain() result_domain_profile = domainLib.profile(self.domain) # Initial parameters. domainAccountSetting = {} self.aliasDomains = [] if result_domain_profile[0] is True: domainProfile = result_domain_profile[1] domainAccountSetting = ldaputils.getAccountSettingFromLdapQueryResult( domainProfile, key='domainName').get(self.domain, {}) self.aliasDomains = domainProfile[0][1].get('domainAliasName', []) # Check password. self.newpw = web.safestr(data.get('newpw')) self.confirmpw = web.safestr(data.get('confirmpw')) result = iredutils.verifyNewPasswords( self.newpw, self.confirmpw, min_passwd_length=domainAccountSetting.get('minPasswordLength', '0'), max_passwd_length=domainAccountSetting.get('maxPasswordLength', '0'), ) if result[0] is True: self.passwd = ldaputils.generatePasswd(result[1]) else: return result # Get display name. self.cn = data.get('cn') # Get user quota. Unit is MB. # 0 or empty is not allowed if domain quota is set, set to # @defaultUserQuota or @domainSpareQuotaSize # Initial final mailbox quota. self.quota = 0 # Get mail quota from web form. defaultUserQuota = domainLib.getDomainDefaultUserQuota( self.domain, domainAccountSetting) self.mailQuota = str(data.get('mailQuota')).strip() if self.mailQuota.isdigit(): self.mailQuota = int(self.mailQuota) else: self.mailQuota = defaultUserQuota # 0 means unlimited. domainQuotaSize, domainQuotaUnit = domainAccountSetting.get( 'domainQuota', '0:GB').split(':') if int(domainQuotaSize) == 0: # Unlimited. self.quota = self.mailQuota else: # Get domain quota, convert to MB. if domainQuotaUnit == 'TB': domainQuota = int(domainQuotaSize) * 1024 * 1024 # TB elif domainQuotaUnit == 'GB': domainQuota = int(domainQuotaSize) * 1024 # GB else: domainQuota = int(domainQuotaSize) # MB # TODO Query whole domain and calculate current quota size, not read from domain profile. #domainCurrentQuotaSize = int(domainProfile[0][1].get('domainCurrentQuotaSize', ['0'])[0]) / (1024*1024) result = connutils.getDomainCurrentQuotaSizeFromLDAP( domain=self.domain) if result[0] is True: domainCurrentQuotaSize = result[1] else: domainCurrentQuotaSize = 0 # Spare quota. domainSpareQuotaSize = domainQuota - domainCurrentQuotaSize / ( 1024 * 1024) if domainSpareQuotaSize <= 0: return (False, 'EXCEEDED_DOMAIN_QUOTA_SIZE') # Get FINAL mailbox quota. if self.mailQuota == 0: self.quota = domainSpareQuotaSize else: if domainSpareQuotaSize > self.mailQuota: self.quota = self.mailQuota else: self.quota = domainSpareQuotaSize # Get default groups. self.groups = [ web.safestr(v) for v in domainAccountSetting.get('defaultList', '').split(',') if iredutils.isEmail(v) ] self.defaultStorageBaseDirectory = domainAccountSetting.get( 'defaultStorageBaseDirectory', None) # Get default mail list which set in domain accountSetting. ldif = iredldif.ldif_mailuser( domain=self.domain, aliasDomains=self.aliasDomains, username=self.username, cn=self.cn, passwd=self.passwd, quota=self.quota, groups=self.groups, storageBaseDirectory=self.defaultStorageBaseDirectory, ) if attrs.RDN_USER == 'mail': self.dn = ldaputils.convKeywordToDN(self.mail, accountType='user') elif attrs.RDN_USER == 'cn': self.dn = 'cn=' + self.cn + ',' + attrs.DN_BETWEEN_USER_AND_DOMAIN + \ ldaputils.convKeywordToDN(self.domain, accountType='domain') elif attrs.RDN_USER == 'uid': self.dn = 'uid=' + self.username + ',' + attrs.DN_BETWEEN_USER_AND_DOMAIN + \ ldaputils.convKeywordToDN(self.domain, accountType='domain') else: return (False, 'UNSUPPORTED_USER_RDN') try: self.conn.add_s( ldap.filter.escape_filter_chars(self.dn), ldif, ) web.logger( msg="Create user: %s." % (self.mail), domain=self.domain, event='create', ) return (True, ) except ldap.ALREADY_EXISTS: return (False, 'ALREADY_EXISTS') except Exception, e: return (False, ldaputils.getExceptionDesc(e))
def add(self, domain, data): # Get domain name, username, cn. self.domain = web.safestr(data.get("domainName")).strip().lower() self.username = web.safestr(data.get("username")).strip().lower() self.mail = self.username + "@" + self.domain self.groups = data.get("groups", []) if not iredutils.is_domain(self.domain) or not iredutils.is_email(self.mail): return (False, "MISSING_DOMAIN_OR_USERNAME") # Check account existing. connutils = connUtils.Utils() if connutils.isAccountExists(domain=self.domain, mail=self.mail): return (False, "ALREADY_EXISTS") # Get @domainAccountSetting. domainLib = domainlib.Domain() result_domain_profile = domainLib.profile(domain=self.domain) # Initial parameters. domainAccountSetting = {} self.aliasDomains = [] if result_domain_profile[0] is not True: return (False, result_domain_profile[1]) domainProfile = result_domain_profile[1] domainAccountSetting = ldaputils.getAccountSettingFromLdapQueryResult(domainProfile, key="domainName").get( self.domain, {} ) self.aliasDomains = domainProfile[0][1].get("domainAliasName", []) # Check account number limit. numberOfAccounts = domainAccountSetting.get("numberOfUsers") if numberOfAccounts == "-1": return (False, "NOT_ALLOWED") # Check password. self.newpw = web.safestr(data.get("newpw")) self.confirmpw = web.safestr(data.get("confirmpw")) result = iredutils.verify_new_password( self.newpw, self.confirmpw, min_passwd_length=domainAccountSetting.get("minPasswordLength", "0"), max_passwd_length=domainAccountSetting.get("maxPasswordLength", "0"), ) if result[0] is True: if "storePasswordInPlainText" in data and settings.STORE_PASSWORD_IN_PLAIN_TEXT: self.passwd = iredutils.generate_password_hash(result[1], pwscheme="PLAIN") else: self.passwd = iredutils.generate_password_hash(result[1]) else: return result # Get display name. self.cn = data.get("cn") # Get user quota. Unit is MB. # 0 or empty is not allowed if domain quota is set, set to # @defaultUserQuota or @domainSpareQuotaSize # Initial final mailbox quota. self.quota = 0 # Get mail quota from web form. defaultUserQuota = domainLib.getDomainDefaultUserQuota(self.domain, domainAccountSetting) self.mailQuota = str(data.get("mailQuota")).strip() if self.mailQuota.isdigit(): self.mailQuota = int(self.mailQuota) else: self.mailQuota = defaultUserQuota # 0 means unlimited. domainQuotaSize, domainQuotaUnit = domainAccountSetting.get("domainQuota", "0:GB").split(":") if int(domainQuotaSize) == 0: # Unlimited. self.quota = self.mailQuota else: # Get domain quota, convert to MB. if domainQuotaUnit == "TB": domainQuota = int(domainQuotaSize) * 1024 * 1024 # TB elif domainQuotaUnit == "GB": domainQuota = int(domainQuotaSize) * 1024 # GB else: domainQuota = int(domainQuotaSize) # MB result = connutils.getDomainCurrentQuotaSizeFromLDAP(domain=self.domain) if result[0] is True: domainCurrentQuotaSize = result[1] else: domainCurrentQuotaSize = 0 # Spare quota. domainSpareQuotaSize = domainQuota - domainCurrentQuotaSize / (1024 * 1024) if domainSpareQuotaSize <= 0: return (False, "EXCEEDED_DOMAIN_QUOTA_SIZE") # Get FINAL mailbox quota. if self.mailQuota == 0: self.quota = domainSpareQuotaSize else: if domainSpareQuotaSize > self.mailQuota: self.quota = self.mailQuota else: self.quota = domainSpareQuotaSize # Get default groups. self.groups = [ web.safestr(v) for v in domainAccountSetting.get("defaultList", "").split(",") if iredutils.is_email(v) ] self.defaultStorageBaseDirectory = domainAccountSetting.get("defaultStorageBaseDirectory", None) # Get default mail lists which set in domain accountSetting. ldif = iredldif.ldif_mailuser( domain=self.domain, aliasDomains=self.aliasDomains, username=self.username, cn=self.cn, passwd=self.passwd, quota=self.quota, groups=self.groups, storageBaseDirectory=self.defaultStorageBaseDirectory, ) domain_dn = ldaputils.convert_keyword_to_dn(self.domain, accountType="domain") if domain_dn[0] is False: return domain_dn if attrs.RDN_USER == "mail": self.dn = ldaputils.convert_keyword_to_dn(self.mail, accountType="user") if self.dn[0] is False: return self.dn elif attrs.RDN_USER == "cn": self.dn = "cn=" + self.cn + "," + attrs.DN_BETWEEN_USER_AND_DOMAIN + domain_dn elif attrs.RDN_USER == "uid": self.dn = "uid=" + self.username + "," + attrs.DN_BETWEEN_USER_AND_DOMAIN + domain_dn else: return (False, "UNSUPPORTED_USER_RDN") try: self.conn.add_s(ldap.filter.escape_filter_chars(self.dn), ldif) web.logger(msg="Create user: %s." % (self.mail), domain=self.domain, event="create") return (True,) except ldap.ALREADY_EXISTS: return (False, "ALREADY_EXISTS") except Exception, e: return (False, ldaputils.getExceptionDesc(e))