def getAvailableDomainNames(self, domain): '''Get list of domainName and domainAliasName by quering domainName. >>> getAvailableDomainNames(domain='example.com') (True, ['example.com', 'aliasdomain01.com', 'aliasdomain02.com', ...]) ''' domain = web.safestr(domain).strip().lower() if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') dn = ldaputils.convert_keyword_to_dn(domain, accountType='domain') try: result = self.conn.search_s( dn, ldap.SCOPE_BASE, '(&(objectClass=mailDomain)(domainName=%s))' % domain, ['domainName', 'domainAliasName'], ) all_domains = result[0][1].get('domainName', []) + result[0][1].get('domainAliasName', []) all_domains = [str(d).lower() for d in all_domains if iredutils.is_domain(d)] return (True, all_domains) except Exception as e: return (False, ldaputils.getExceptionDesc(e))
def GET(self, profile_type, mail): i = web.input() self.mail = str(mail).lower() self.cur_domain = self.mail.split('@', 1)[-1] self.profile_type = str(profile_type) if self.mail.startswith('@') and iredutils.is_domain(self.cur_domain): # Catchall account. raise web.seeother('/profile/domain/catchall/%s' % self.cur_domain) if not iredutils.is_email(self.mail): raise web.seeother('/domains?msg=INVALID_USER') if not iredutils.is_domain(self.cur_domain): raise web.seeother('/domains?msg=INVALID_DOMAIN_NAME') userLib = userlib.User() qr = userLib.profile(domain=self.cur_domain, mail=self.mail) if qr[0] is True: self.profile = qr[1] else: raise web.seeother('/users/%s?msg=%s' % (self.cur_domain, web.urlquote(qr[1]))) return web.render( 'pgsql/user/profile.html', cur_domain=self.cur_domain, mail=self.mail, profile_type=self.profile_type, profile=self.profile, languagemaps=get_language_maps(), msg=i.get('msg'), )
def get_multi_values(form, input_name, default_value=None, input_is_textarea=False, is_domain=False, is_email=False, to_lowercase=False, to_uppercase=False): v = form.get(input_name) if v: if input_is_textarea: v = v.splitlines() else: v = default_value # Remove duplicate items. v = list(set(v)) if is_domain: v = [str(i).lower() for i in v if iredutils.is_domain(i)] if is_email: v = [str(i).lower() for i in v if iredutils.is_email(i)] if to_lowercase: if not (is_domain or is_email): v = [i.lower() for i in v] if to_uppercase: if not (is_domain or is_email): v = [i.upper() for i in v] return v
def setAccountStatus(self, accounts, accountType, active=True): # accounts must be a list/tuple. # accountType in ['domain', 'user', 'admin', 'alias',] # active: True -> active, False -> disabled if not len(accounts) > 0: return (True, ) accountType = str(accountType) if active is True: active = 1 action = 'Active' else: active = 0 action = 'Disable' if accountType == 'domain': accounts = [str(v) for v in accounts if iredutils.is_domain(v)] try: self.conn.update( 'domain', vars={'accounts': accounts}, where='domain IN $accounts', active=active, ) except Exception, e: return (False, str(e))
def GET(self, domain, cur_page=1): self.domain = web.safestr(domain).split('/', 1)[0] cur_page = int(cur_page) if not iredutils.is_domain(self.domain): raise web.seeother('/domains?msg=INVALID_DOMAIN_NAME') if cur_page == 0: cur_page = 1 userLib = userlib.User() result = userLib.listAccounts(domain=self.domain, cur_page=cur_page,) if result[0] is True: (total, records) = (result[1], result[2]) return web.render( 'pgsql/user/list.html', cur_domain=self.domain, cur_page=cur_page, total=total, users=records, msg=web.input().get('msg', None), ) else: raise web.seeother('/domains?msg=%s' % web.urlquote(result[1]))
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.is_domain(self.domain): raise web.seeother('/domains?msg=EMPTY_DOMAIN') domainLib = domainlib.Domain() result = domainLib.profile(domain=self.domain) if result[0] is False: raise web.seeother('/domains?msg=' + web.urlquote(result[1])) 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), )
def __num_accounts_under_domain(domain, account_type, conn=None) -> int: num = 0 if not iredutils.is_domain(domain): return num if not conn: _wrap = SQLWrap() conn = _wrap.conn # mapping of account types and sql table names mapping = {'user': '******', 'alias': 'alias', 'maillist': 'maillists'} sql_table = mapping[account_type] try: qr = conn.select(sql_table, vars={'domain': domain}, what='COUNT(domain) AS total', where='domain=$domain') if qr: num = qr[0].total except Exception as e: logger.error(e) return num
def getDomainCurrentQuotaSizeFromLDAP(self, domain): self.domain = web.safestr(domain).strip().lower() if not iredutils.is_domain(self.domain): return (False, 'INVALID_DOMAIN_NAME') self.domainDN = ldaputils.convert_keyword_to_dn(self.domain, accountType='domain') # Initial @domainCurrentQuotaSize self.domainCurrentQuotaSize = 0 try: # Use '(!([email protected]))' to hide catch-all account. self.users = self.conn.search_s( attrs.DN_BETWEEN_USER_AND_DOMAIN + self.domainDN, ldap.SCOPE_SUBTREE, '(&(objectClass=mailUser)(!(mail=@%s)))' % self.domain, attrs.USER_SEARCH_ATTRS, ) # Update @domainCurrentUserNumber self.updateAttrSingleValue(self.domainDN, 'domainCurrentUserNumber', len(self.users)) for i in self.users: quota = i[1].get('mailQuota', ['0'])[0] if quota.isdigit(): self.domainCurrentQuotaSize += int(quota) return (True, self.domainCurrentQuotaSize) except ldap.NO_SUCH_OBJECT: return (False, 'NO_SUCH_OBJECT') except ldap.SIZELIMIT_EXCEEDED: return (False, 'EXCEEDED_LDAP_SERVER_SIZELIMIT') except Exception as e: return (False, ldaputils.getExceptionDesc(e))
def POST(self, domain): i = web.input(_unicode=False, mail=[]) self.domain = str(domain) if not iredutils.is_domain(self.domain): raise web.seeother('/domains?msg=INVALID_DOMAIN_NAME') self.mails = [str(v) for v in i.get('mail', []) if iredutils.is_email(v) and str(v).endswith('@' + self.domain) ] action = i.get('action', '') msg = i.get('msg', None) userLib = userlib.User() if action == 'delete': result = userLib.delete(domain=self.domain, mails=self.mails,) msg = 'DELETED' elif action == 'disable': result = userLib.enableOrDisableAccount(domain=self.domain, accounts=self.mails, active=False) msg = 'DISABLED' elif action == 'enable': result = userLib.enableOrDisableAccount(domain=self.domain, accounts=self.mails, active=True) msg = 'ENABLED' else: result = (False, 'INVALID_ACTION') if result[0] is True: raise web.seeother('/users/%s?msg=%s' % (self.domain, msg,)) else: raise web.seeother('/users/%s?msg=%s' % (self.domain, web.urlquote(result[1]),))
def getNumberOfManagedAccounts(self, admin=None, accountType='domain', domains=[],): if admin is None: admin = session.get('username') else: admin = str(admin) if not iredutils.is_email(admin): return 0 domains = [] if len(domains) > 0: domains = [str(d).lower() for d in domains if iredutils.is_domain(d)] else: connutils = connUtils.Utils() qr = connutils.getManagedDomains(mail=admin, attrs=['domainName'], listedOnly=True) if qr[0] is True: domains = qr[1] if accountType == 'domain': try: return len(domains) except Exception: pass return 0
def simple_profile(domain, columns=None, conn=None): if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') sql_what = '*' if columns: sql_what = ','.join(columns) try: if not conn: _wrap = SQLWrap() conn = _wrap.conn qr = conn.select('domain', vars={'domain': domain}, what=sql_what, where='domain=$domain', limit=1) if qr: p = list(qr)[0] return (True, p) else: return (False, 'INVALID_DOMAIN_NAME') except Exception as e: return (False, repr(e))
def assign_admins_to_domain(domain, admins, conn=None): """Assign list of NEW admins to specified mail domain. It doesn't remove existing admins.""" if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') if not isinstance(admins, (list, tuple, set)): return (False, 'NO_ADMINS') else: admins = [str(i).lower() for i in admins if iredutils.is_email(i)] if not admins: return (False, 'NO_ADMINS') if not conn: _wrap = SQLWrap() conn = _wrap.conn for adm in admins: try: conn.insert('domain_admins', domain=domain, username=adm) except Exception as e: if e.__class__.__name__ == 'IntegrityError': pass else: return (False, repr(e)) return (True, )
def add(self, data): # msg: {key: value} msg = {} self.domain = web.safestr(data.get('domainName', '')).strip().lower() # Check domain name. if not iredutils.is_domain(self.domain): return (False, 'INVALID_DOMAIN_NAME') # Check whether domain name already exist (domainName, domainAliasName). connutils = connUtils.Utils() if connutils.is_domain_exists(self.domain): return (False, 'ALREADY_EXISTS') self.dn = ldaputils.convert_keyword_to_dn(self.domain, accountType='domain') if self.dn[0] is False: return self.dn self.cn = data.get('cn', None) ldif = iredldif.ldif_maildomain(domain=self.domain, cn=self.cn,) # Add domain dn. try: result = self.conn.add_s(self.dn, ldif) web.logger(msg="Create domain: %s." % (self.domain), domain=self.domain, event='create',) except ldap.ALREADY_EXISTS: msg[self.domain] = 'ALREADY_EXISTS' except ldap.LDAPError, e: msg[self.domain] = str(e)
def proxyfunc(*args, **kw): # Check domain global admin. if session.get('domainGlobalAdmin') is True: return func(*args, **kw) else: if 'domain' in list(kw.keys()) and iredutils.is_domain( kw.get('domain')): domain = web.safestr(kw['domain']) elif 'mail' in list(kw.keys()) and iredutils.is_email( kw.get('mail')): domain = web.safestr(kw['mail']).split('@')[-1] elif 'admin' in list(kw.keys()) and iredutils.is_email( kw.get('admin')): domain = web.safestr(kw['admin']).split('@')[-1] else: return (False, 'PERMISSION_DENIED') # Check whether is domain admin. validator = core.PGSQLWrap() if validator.is_domainAdmin( domain=domain, admin=session.get('username'), ): return func(*args, **kw) else: return (False, 'PERMISSION_DENIED')
def delete(self, domains=[]): if not isinstance(domains, list): return (False, 'INVALID_DOMAIN_NAME') domains = [str(v).lower() for v in domains if iredutils.is_domain(v)] if not domains: return (True, ) msg = {} for domain in domains: dn = ldaputils.convert_keyword_to_dn(web.safestr(domain), accountType='domain') if dn[0] is False: return dn try: deltree.DelTree(self.conn, dn, ldap.SCOPE_SUBTREE) web.logger( msg="Delete domain: %s." % (domain), domain=domain, event='delete', ) except ldap.LDAPError, e: msg[domain] = str(e)
def add(self, data): domain = web.safestr(data.get('domainName', '')).strip().lower() # Get company/organization name. cn = data.get('cn', '') # Check domain name. if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') # Check whether domain name already exist (domainName, domainAliasName). connutils = connUtils.Utils() if connutils.is_domain_exists(domain): return (False, 'ALREADY_EXISTS') # Add domain in database. try: self.conn.insert( 'domain', domain=domain, description=cn, transport=settings.default_mta_transport, created=iredutils.get_gmttime(), active='1', ) web.logger( msg="Create domain: %s." % (domain), domain=domain, event='create', ) except Exception, e: return (False, str(e))
def is_domainAdmin( self, domain, admin=session.get('username'), ): if not iredutils.is_domain(domain) or not iredutils.is_email(admin): return False if admin == session.get('username') \ and session.get('domainGlobalAdmin') is True: return True try: result = self.conn.select( 'domain_admins', vars={ 'domain': domain, 'username': admin, }, what='username', where='domain=$domain AND username=$username AND active=1', limit=1, ) if len(result) == 1: return True else: return False except Exception: return False
def delete(self, domain, mails=None, keep_mailbox_days=0): if not mails: return (False, 'NO_ACCOUNT_SELECTED') self.domain = web.safestr(domain) self.mails = [ str(v) for v in mails if iredutils.is_email(v) and str(v).endswith('@' + self.domain) ] if not len(self.mails) > 0: return (False, 'INVALID_MAIL') if not iredutils.is_domain(self.domain): return (False, 'INVALID_DOMAIN_NAME') self.domaindn = ldaputils.convert_keyword_to_dn(self.domain, accountType='domain') result = {} for mail in self.mails: self.mail = web.safestr(mail) try: # Delete user object (ldap.SCOPE_BASE). self.deleteSingleUser(mail=self.mail, keep_mailbox_days=keep_mailbox_days) except ldap.LDAPError as e: result[self.mail] = ldaputils.getExceptionDesc(e) if result == {}: return (True, ) else: return (False, str(result))
def set_account_status(conn, accounts, account_type, enable_account=False): """Set account status. accounts -- an iterable object (list/tuple) filled with accounts. account_type -- possible value: domain, admin, user, alias enable_account -- possible value: True, False """ if account_type in ['admin', 'user']: # email accounts = [str(v).lower() for v in accounts if iredutils.is_email(v)] else: # domain name accounts = [str(v).lower() for v in accounts if iredutils.is_domain(v)] if not accounts: return (True, ) # 0: disable, 1: enable account_status = 0 action = 'disable' if enable_account: account_status = 1 action = 'active' if account_type == 'domain': # handle with function which handles admin privilege qr = sql_lib_domain.enable_disable_domains(domains=accounts, action=action) return qr elif account_type == 'admin': # [(<table>, <column-used-for-query>), ...] table_column_maps = [("admin", "username")] elif account_type == 'alias': table_column_maps = [ ("alias", "address"), ("forwardings", "address"), ] else: # account_type == 'user' table_column_maps = [ ("mailbox", "username"), ("forwardings", "address"), ] for (_table, _column) in table_column_maps: sql_where = '{} IN {}'.format(_column, web.sqlquote(accounts)) try: conn.update(_table, where=sql_where, active=account_status) except Exception as e: return (False, repr(e)) log_activity(event=action, msg="{} {}: {}.".format(action.title(), account_type, ', '.join(accounts))) return (True, )
def getManagedDomains(self, admin, domainNameOnly=False, listedOnly=False,): admin = web.safestr(admin) if not iredutils.is_email(admin): return (False, 'INCORRECT_USERNAME') sql_left_join = '' if listedOnly is False: sql_left_join = """OR domain_admins.domain='ALL'""" try: result = self.conn.query( """ SELECT domain.domain FROM domain LEFT JOIN domain_admins ON (domain.domain=domain_admins.domain %s) WHERE domain_admins.username=$admin ORDER BY domain_admins.domain """ % (sql_left_join), vars={'admin': admin, }, ) if domainNameOnly is True: domains = [] for i in result: if iredutils.is_domain(i.domain): domains += [str(i.domain).lower()] return (True, domains) else: return (True, list(result)) except Exception, e: return (False, str(e))
def listAccounts(self, domain, cur_page=1): """List all users.""" if not iredutils.is_domain(domain): return (False, "INVALID_DOMAIN_NAME") domain = str(domain) connutils = connUtils.Utils() if not connutils.is_domain_exists(domain): return (False, "PERMISSION_DENIED") # Pre-defined. sql_vars = {"domain": domain} total = 0 try: resultOfTotal = self.conn.select( "mailbox", vars=sql_vars, what="COUNT(username) AS total", where="domain=$domain" ) if len(resultOfTotal) == 1: total = resultOfTotal[0].total or 0 resultOfRecords = self.conn.select( "mailbox", vars=sql_vars, # Just query what we need to reduce memory use. what="username,name,quota,employeeid,active", where="domain=$domain", order="username ASC", limit=settings.PAGE_SIZE_LIMIT, offset=(cur_page - 1) * settings.PAGE_SIZE_LIMIT, ) return (True, total, list(resultOfRecords)) except Exception, e: return (False, str(e))
def deleteObjWithDN( self, domain, dn, account, accountType, ): self.domain = web.safestr(domain) if not iredutils.is_domain(self.domain): return (False, 'INVALID_DOMAIN_NAME') self.dn = escape_filter_chars(dn) # Used for logger. self.account = web.safestr(account) try: delete_ldap_tree(dn=self.dn, conn=self.conn) web.logger( msg="Delete %s: %s." % (str(accountType), self.account), domain=self.domain, event='delete', ) return (True, ) except Exception, e: return (False, ldaputils.getExceptionDesc(e))
def is_domain_exists(self, domain): # Return True if account is invalid or exist. self.domain = web.safestr(domain).strip().lower() # Check domain name. if not iredutils.is_domain(self.domain): # Return True if invalid. return True # Check domainName and domainAliasName. try: result = self.conn.search_s( settings.ldap_basedn, ldap.SCOPE_ONELEVEL, '(|(domainName=%s)(domainAliasName=%s))' % (self.domain, self.domain), [ 'domainName', 'domainAliasName', ], ) if len(result) > 0: # Domain name exist. return True else: return False except: return True
def getManagedDomains( self, admin, domainNameOnly=False, listedOnly=False, ): admin = web.safestr(admin) if not iredutils.is_email(admin): return (False, 'INCORRECT_USERNAME') try: result = self.conn.select('domain') if domainNameOnly is True: domains = [] for i in result: if iredutils.is_domain(i.domain): domains += [str(i.domain).lower()] return (True, domains) else: return (True, list(result)) except Exception as e: return (False, str(e))
def getCountsOfExistAccountsUnderDomain(self, domain, accountType='user'): if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') sql_vars = { 'domain': domain, } if accountType == 'user': try: qr1 = self.conn.select( 'mailbox', vars=sql_vars, what='COUNT(username) AS mailbox_count', where='domain=$domain', ) mailbox_count = qr1[0].mailbox_count or 0 qr2 = self.conn.select( 'mailbox', vars=sql_vars, what='SUM(quota) AS quota_count', where='domain=$domain', ) quota_count = qr2[0].quota_count or 0 return (True, mailbox_count, quota_count) except Exception, e: return (False, str(e))
def delete(self, domain, mails=[]): domain = str(domain) if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') if not isinstance(mails, list): return (False, 'INVALID_MAIL') mails = [str(v).lower() for v in mails if iredutils.is_email(v) and str(v).endswith('@' + domain)] if not mails: return (False, 'INVALID_MAIL') # Delete user and related records. try: qr = self.deleteAccounts(accounts=mails, accountType='user') if qr[0] is True: web.logger( msg="Delete user: %s." % ', '.join(mails), domain=domain, event='delete', ) else: return qr return (True,) except Exception, e: return (False, str(e))
def getDomainAdmins(self, domain, mailOnly=False): domain = str(domain) if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') try: qr = self.conn.query( ''' SELECT admin.username, admin.name, admin.language, admin.active FROM admin LEFT JOIN domain_admins ON (domain_admins.username=admin.username) WHERE domain_admins.domain=$domain ''', vars={ 'domain': domain, }, ) if mailOnly is True: admins = [] for adm in qr: admins += [adm.username] return (True, admins) else: return (True, list(qr)) except Exception, e: return (False, str(e))
def proxyfunc(self, *args, **kw): if 'mail' in kw.keys() and iredutils.is_email(kw.get('mail')): self.domain = web.safestr(kw['mail']).split('@')[-1] elif 'domain' in kw.keys() and iredutils.is_domain(kw.get('domain')): self.domain = web.safestr(kw['domain']) else: return False self.admin = session.get('username') if not iredutils.is_email(self.admin): return False # Check domain global admin. if session.get('domainGlobalAdmin') is True: return func(self, *args, **kw) else: # Check whether is domain admin. try: result = self.conn.select( 'domain_admins', vars={'username': self.admin, 'domain': [self.domain, 'ALL']}, what='username', where='username=$username AND domain IN $domain', ) except Exception: result = {} if len(result) != 1: return func(self, *args, **kw) else: raise web.seeother('/users' + '?msg=PERMISSION_DENIED&domain=' + self.domain)
def getCountsOfExistAccountsUnderDomain(self, domain, accountType='user'): if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') sql_vars = {'domain': domain, } if accountType == 'user': try: qr1 = self.conn.select( 'mailbox', vars=sql_vars, what='COUNT(username) AS mailbox_count', where='domain=$domain', ) mailbox_count = qr1[0].mailbox_count or 0 qr2 = self.conn.select( 'mailbox', vars=sql_vars, what='SUM(quota) AS quota_count', where='domain=$domain', ) quota_count = qr2[0].quota_count or 0 return (True, mailbox_count, quota_count) except Exception, e: return (False, str(e))
def delete(self, domain, mails=None, keep_mailbox_days=0): domain = str(domain).lower() if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') if not mails: return (False, 'INVALID_MAIL') mails = [ str(v).lower() for v in mails if iredutils.is_email(v) and str(v).endswith('@' + domain) ] if not mails: return (False, 'INVALID_MAIL') # Delete user and related records. try: qr = self.deleteAccounts(accounts=mails, accountType='user', keep_mailbox_days=keep_mailbox_days) if qr[0] is True: web.logger( msg="Delete user: %s." % ', '.join(mails), domain=domain, event='delete', ) else: return qr return (True, ) except Exception as e: return (False, str(e))
def add(self, data): domain = web.safestr(data.get('domainName', '')).strip().lower() # Get company/organization name. cn = data.get('cn', '') # Check domain name. if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') # Check whether domain name already exist (domainName, domainAliasName). connutils = connUtils.Utils() if connutils.is_domain_exists(domain): return (False, 'ALREADY_EXISTS') # Add domain in database. try: self.conn.insert( 'domain', domain=domain, description=cn, transport=settings.default_mta_transport, created=iredutils.get_gmttime(), active='1', ) web.logger(msg="Create domain: %s." % (domain), domain=domain, event='create',) except Exception, e: return (False, str(e))
def setAccountStatus(self, accounts, accountType, active=True): # accounts must be a list/tuple. # accountType in ['domain', 'user', 'admin', 'alias',] # active: True -> active, False -> disabled if not len(accounts) > 0: return (True,) accountType = str(accountType) if active is True: active = 1 action = 'Active' else: active = 0 action = 'Disable' if accountType == 'domain': accounts = [str(v) for v in accounts if iredutils.is_domain(v)] try: self.conn.update( 'domain', vars={'accounts': accounts}, where='domain IN $accounts', active=active, ) except Exception, e: return (False, str(e))
def get_domain_used_quota(conn, domains=None): used_quota = {} if not domains: return used_quota domains = [str(d).lower() for d in domains if iredutils.is_domain(d)] try: qr = conn.select( settings.SQL_TBL_USED_QUOTA, vars={'domains': domains}, where='domain IN $domains', what='domain,SUM(bytes) AS size, SUM(messages) AS messages', group='domain', order='domain', ) for r in qr: used_quota[str(r.domain)] = { 'size': r.size, 'messages': r.messages } except: pass return used_quota
def profile(domain, conn=None): domain = str(domain).lower() if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') if not conn: _wrap = SQLWrap() conn = _wrap.conn try: # Get domain profile first. _qr = simple_profile(domain=domain, conn=conn) if _qr[0]: _profile = _qr[1] else: return _qr # num_existing_users _profile[ 'num_existing_users'] = sql_lib_general.num_users_under_domain( domain=domain, conn=conn) return (True, _profile) except Exception as e: return (False, repr(e))
def proxyfunc(self, *args, **kw): if 'mail' in list(kw.keys()) and iredutils.is_email(kw.get('mail')): self.domain = web.safestr(kw['mail']).split('@')[-1] elif 'domain' in list(kw.keys()) and iredutils.is_domain(kw.get('domain')): self.domain = web.safestr(kw['domain']) else: return False self.admin = session.get('username') if not iredutils.is_email(self.admin): return False # Check domain global admin. if session.get('domainGlobalAdmin') is True: return func(self, *args, **kw) else: # Check whether is domain admin. try: result = self.conn.select( 'domain_admins', vars={'username': self.admin, 'domain': [self.domain, 'ALL']}, what='username', where='username=$username AND domain IN $domain', ) except Exception: result = {} if len(result) != 1: return func(self, *args, **kw) else: raise web.seeother('/users' + '?msg=PERMISSION_DENIED&domain=' + self.domain)
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.is_domain(self.domain): raise web.seeother('/domains?msg=EMPTY_DOMAIN') domainLib = domainlib.Domain() result = domainLib.profile(domain=self.domain) if result[0] is False: raise web.seeother('/domains?msg=' + web.urlquote(result[1])) 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), )
def getDomainAdmins(self, domain, mailOnly=False): domain = str(domain) if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') try: qr = self.conn.query( ''' SELECT admin.username, admin.name, admin.language, admin.active FROM admin LEFT JOIN domain_admins ON (domain_admins.username=admin.username) WHERE domain_admins.domain=$domain ''', vars={'domain': domain, }, ) if mailOnly is True: admins = [] for adm in qr: admins += [adm.username] return (True, admins) else: return (True, list(qr)) except Exception, e: return (False, str(e))
def delete(self, domains=None, keep_mailbox_days=0): if not domains: return (False, 'INVALID_DOMAIN_NAME') domains = [str(v).lower() for v in domains if iredutils.is_domain(v)] if not domains: return (True, ) if keep_mailbox_days == 0: keep_mailbox_days = 36500 sql_vars = { 'domains': domains, 'admin': session.get('username'), 'keep_mailbox_days': keep_mailbox_days } # Log maildir paths of existing users try: sql_raw = ''' INSERT INTO deleted_mailboxes (username, maildir, domain, admin, delete_date) SELECT username, \ CONCAT(storagebasedirectory, '/', storagenode, '/', maildir) AS maildir, \ domain, \ $admin, \ DATE_ADD(NOW(), INTERVAL $keep_mailbox_days DAY) FROM mailbox WHERE domain IN $domains''' self.conn.query(sql_raw, vars=sql_vars) except Exception, e: print e pass
def add(self, data): # msg: {key: value} msg = {} self.domain = web.safestr(data.get('domainName', '')).strip().lower() # Check domain name. if not iredutils.is_domain(self.domain): return (False, 'INVALID_DOMAIN_NAME') # Check whether domain name already exist (domainName, domainAliasName). connutils = connUtils.Utils() if connutils.is_domain_exists(self.domain): return (False, 'ALREADY_EXISTS') self.dn = ldaputils.convert_keyword_to_dn(self.domain, accountType='domain') if self.dn[0] is False: return self.dn self.cn = data.get('cn', None) ldif = iredldif.ldif_maildomain(domain=self.domain, cn=self.cn,) # Add domain dn. try: self.conn.add_s(self.dn, ldif) web.logger(msg="Create domain: %s." % (self.domain), domain=self.domain, event='create',) except ldap.ALREADY_EXISTS: msg[self.domain] = 'ALREADY_EXISTS' except ldap.LDAPError, e: msg[self.domain] = str(e)
def profile(self, domain): domain = web.safestr(domain) if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') try: qr = self.conn.query( ''' SELECT domain.domain, domain.description, domain.aliases, domain.mailboxes, domain.maxquota, domain.quota, domain.transport, domain.backupmx, domain.active, sbcc.bcc_address AS sbcc_addr, sbcc.active AS sbcc_active, rbcc.bcc_address AS rbcc_addr, rbcc.active AS rbcc_active, alias.goto AS catchall, alias.active AS catchall_active, COUNT(DISTINCT mailbox.username) AS mailbox_count, COUNT(DISTINCT alias.address) AS alias_count FROM domain LEFT JOIN sender_bcc_domain AS sbcc ON (sbcc.domain=domain.domain) LEFT JOIN recipient_bcc_domain AS rbcc ON (rbcc.domain=domain.domain) LEFT JOIN domain_admins ON (domain.domain = domain_admins.domain) LEFT JOIN mailbox ON (domain.domain = mailbox.domain) LEFT JOIN alias ON ( domain.domain = alias.address AND alias.address <> alias.goto ) WHERE domain.domain=$domain GROUP BY domain.domain, domain.description, domain.aliases, domain.mailboxes, domain.maxquota, domain.quota, domain.transport, domain.backupmx, domain.active, sbcc.bcc_address, sbcc.active, rbcc.bcc_address, rbcc.active, alias.goto, alias.active ORDER BY domain.domain LIMIT 1 ''', vars={'domain': domain, }, ) if len(qr) == 1: # Return first list element. return (True, list(qr)[0]) else: return (False, 'NO_SUCH_OBJECT') except Exception, e: return (False, str(e))
def delete(self, domains=[]): if not isinstance(domains, list): return (False, 'INVALID_DOMAIN_NAME') domains = [str(v).lower() for v in domains if iredutils.is_domain(v) ] if not domains: return (True, ) sql_vars = {'domains': domains, } # Delete domain and related records. try: self.conn.delete('domain', vars=sql_vars, where='domain IN $domains', ) self.conn.delete( 'alias_domain', vars=sql_vars, where='alias_domain IN $domains OR target_domain IN $domains', ) for tbl in ['alias', 'domain_admins', 'mailbox', \ 'recipient_bcc_domain', 'recipient_bcc_user', \ 'sender_bcc_domain', 'sender_bcc_user', \ ]: self.conn.delete( tbl, vars=sql_vars, where='domain IN $domains', ) # Delete real-time mailbox quota. try: self.conn.query( 'DELETE FROM used_quota WHERE %s' % \ web.sqlors('username LIKE ', ['%@' + d for d in domains]) ) except: pass for d in domains: web.logger(msg="Delete domain: %s." % (d), domain=d, event='delete',) return (True,) except Exception, e: return (False, str(e))
def GET(self, domain='', cur_page=1): domain = web.safestr(domain).split('/', 1)[0] cur_page = int(cur_page) if not iredutils.is_domain(domain): raise web.seeother('/domains?msg=INVALID_DOMAIN_NAME') if cur_page == 0: cur_page = 1 i = web.input() domainLib = domainlib.Domain() result = domainLib.listAccounts(attrs=['domainName', 'accountStatus', ]) if result[0] is True: allDomains = result[1] else: return result userLib = user.User() result = userLib.listAccounts(domain=domain) if result[0] is True: connutils = connUtils.Utils() sl = connutils.getSizelimitFromAccountLists( result[1], curPage=cur_page, sizelimit=settings.PAGE_SIZE_LIMIT, accountType='user', domain=domain, ) accountList = sl.get('accountList', []) if cur_page > sl.get('totalPages'): cur_page = sl.get('totalPages') return web.render( 'ldap/user/list.html', cur_page=cur_page, total=sl.get('totalAccounts'), users=accountList, cur_domain=domain, allDomains=allDomains, accountUsedQuota={}, msg=i.get('msg'), ) else: raise web.seeother('/domains?msg=%s' % web.urlquote(result[1]))
def listLogs(self, event='all', domain='all', admin='all', cur_page=1): self.event = web.safestr(event) self.domain = web.safestr(domain) self.admin = web.safestr(admin) self.cur_page = int(cur_page) # Generate a dictionary, converted to an SQL WHERE clause. queryDict = {} if self.event in LOG_EVENTS and self.event != 'all': queryDict['event'] = self.event if iredutils.is_domain(self.domain): queryDict['domain'] = self.domain if session.get('domainGlobalAdmin') is not True: queryDict['admin'] = session.get('username') else: if iredutils.is_email(self.admin): queryDict['admin'] = self.admin # Get number of total records. if len(queryDict) == 0: qr = db.select('log', what='COUNT(timestamp) AS total',) else: qr = db.select('log', what='COUNT(timestamp) AS total', where=web.db.sqlwhere(queryDict),) self.total = qr[0].total or 0 # Get records. if len(queryDict) == 0: # No addition filter. self.entries = db.select( 'log', offset=(self.cur_page - 1) * settings.PAGE_SIZE_LIMIT, limit=settings.PAGE_SIZE_LIMIT, order='timestamp DESC', ) else: # With filter. self.entries = db.select('log', where=web.db.sqlwhere(queryDict), offset=(self.cur_page - 1) * settings.PAGE_SIZE_LIMIT, limit=settings.PAGE_SIZE_LIMIT, order='timestamp DESC', ) return (self.total, list(self.entries))
def deleteObjWithDN(self, domain, dn, account, accountType): self.domain = web.safestr(domain) if not iredutils.is_domain(self.domain): return (False, "INVALID_DOMAIN_NAME") self.dn = escape_filter_chars(dn) # Used for logger. self.account = web.safestr(account) try: deltree.DelTree(self.conn, self.dn, ldap.SCOPE_SUBTREE) web.logger(msg="Delete %s: %s." % (str(accountType), self.account), domain=self.domain, event="delete") return (True,) except Exception, e: return (False, ldaputils.getExceptionDesc(e))
def proxyfunc(*args, **kw): # Check domain global admin. if session.get('domainGlobalAdmin') is True: return func(*args, **kw) else: if 'mail' in kw.keys() and iredutils.is_email(kw.get('mail')): domain = web.safestr(kw['mail']).split('@')[-1] elif 'domain' in kw.keys() and iredutils.is_domain(kw.get('domain')): domain = web.safestr(kw['domain']) else: return (False, 'PERMISSION_DENIED') # Check whether is domain admin. validator = Validator() if validator.is_domainAdmin(domain=domain, admin=session.get('username'),): return func(*args, **kw) else: return (False, 'PERMISSION_DENIED')
def deleteAccounts(self, accounts, accountType,): # accounts must be a list/tuple. # accountType in ['domain', 'user', 'admin', 'alias',] if not accounts: return (True,) accountType = str(accountType) if accountType == 'domain': accounts = [str(v) for v in accounts if iredutils.is_domain(v)] try: self.conn.delete( 'domain', vars={'accounts': accounts, }, where='domain IN $accounts', ) except Exception, e: return (False, str(e))
def GET(self, domain=None,): if domain is None: self.cur_domain = None else: self.cur_domain = str(domain) if not iredutils.is_domain(self.cur_domain): raise web.seeother('/domains?msg=INVALID_DOMAIN_NAME') i = web.input() # Get all managed domains. connutils = connUtils.Utils() qr = connutils.getManagedDomains(admin=session.get('username'), domainNameOnly=True,) if qr[0] is True: allDomains = qr[1] else: raise web.seeother('/domains?msg=' % web.urlquote(qr[1])) # Set first domain as current domain. if self.cur_domain is None: if len(allDomains) > 0: raise web.seeother('/create/user/%s' % str(allDomains[0])) else: raise web.seeother('/domains?msg=NO_DOMAIN_AVAILABLE') # Get domain profile. domainLib = domainlib.Domain() resultOfProfile = domainLib.profile(domain=self.cur_domain) if resultOfProfile[0] is True: self.profile = resultOfProfile[1] else: raise web.seeother('/domains?msg=%s' % web.urlquote(resultOfProfile[1])) return web.render( 'pgsql/user/create.html', cur_domain=self.cur_domain, allDomains=allDomains, profile=self.profile, min_passwd_length=settings.min_passwd_length, max_passwd_length=settings.max_passwd_length, msg=i.get('msg'), )
def GET(self, profile_type, mail): i = web.input(enabledService=[], telephoneNumber=[], ) self.mail = web.safestr(mail) self.cur_domain = self.mail.split('@', 1)[-1] self.profile_type = web.safestr(profile_type) if self.mail.startswith('@') and iredutils.is_domain(self.cur_domain): # Catchall account. raise web.seeother('/profile/domain/catchall/%s' % self.cur_domain) if not iredutils.is_email(self.mail): raise web.seeother('/domains?msg=INVALID_USER') domainAccountSetting = {} userLib = user.User() result = userLib.profile(domain=self.cur_domain, mail=self.mail) if result[0] is False: raise web.seeother('/users/%s?msg=%s' % (self.cur_domain, web.urlquote(result[1]))) if self.profile_type == 'password': # Get accountSetting of current domain. domainLib = domainlib.Domain() result_setting = domainLib.getDomainAccountSetting(domain=self.cur_domain) if result_setting[0] is True: domainAccountSetting = result_setting[1] minPasswordLength = domainAccountSetting.get('minPasswordLength', '0') maxPasswordLength = domainAccountSetting.get('maxPasswordLength', '0') return web.render( 'ldap/user/profile.html', profile_type=self.profile_type, mail=self.mail, user_profile=result[1], defaultStorageBaseDirectory=settings.storage_base_directory, minPasswordLength=minPasswordLength, maxPasswordLength=maxPasswordLength, domainAccountSetting=domainAccountSetting, languagemaps=get_language_maps(), msg=i.get('msg', None), )
def simpleProfile(self, domain, columns=[]): domain = web.safestr(domain) if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') try: qr = self.conn.select('domain', vars={'domain': domain, }, what=','.join(columns) or '*', where='domain=$domain', ) if len(qr) == 1: # Return first list element. return (True, list(qr)[0]) else: return (False, 'NO_SUCH_OBJECT') except Exception, e: return (False, str(e))
def is_domainAdmin(self, domain, admin=session.get('username'),): if not iredutils.is_domain(domain) or not iredutils.is_email(admin): return False if admin == session.get('username') \ and session.get('domainGlobalAdmin') is True: return True try: result = self.conn.select( 'domain_admins', vars={'domain': domain, 'username': admin, }, what='username', where='domain=$domain AND username=$username AND active=1', limit=1, ) if len(result) == 1: return True else: return False except Exception: return False
def delete(self, domain, mails=[]): if mails is None or len(mails) == 0: return (False, "NO_ACCOUNT_SELECTED") self.domain = web.safestr(domain) self.mails = [str(v) for v in mails if iredutils.is_email(v) and str(v).endswith("@" + self.domain)] if not len(self.mails) > 0: return (False, "INVALID_MAIL") self.domaindn = ldaputils.convert_keyword_to_dn(self.domain, accountType="domain") if self.domaindn[0] is False: return self.domaindn if not iredutils.is_domain(self.domain): return (False, "INVALID_DOMAIN_NAME") result = {} for mail in self.mails: self.mail = web.safestr(mail) try: # Delete user object (ldap.SCOPE_BASE). self.deleteSingleUser(self.mail) # Delete user object and whole sub-tree. # Get dn of mail user and domain. """ self.userdn = ldaputils.convert_keyword_to_dn(self.mail, accountType='user') deltree.DelTree(self.conn, self.userdn, ldap.SCOPE_SUBTREE) # Log delete action. web.logger( msg="Delete user: %s." % (self.mail), domain=self.mail.split('@')[1], event='delete', ) """ except ldap.LDAPError, e: result[self.mail] = ldaputils.getExceptionDesc(e)
def getAvailableDomainNames(self, domain): """Get list of domainName and domainAliasName by quering domainName. >>> getAvailableDomainNames(domain='example.com') (True, ['example.com', 'aliasdomain01.com', 'aliasdomain02.com', ...]) """ domain = web.safestr(domain).strip().lower() if not iredutils.is_domain(domain): return (False, "INVALID_DOMAIN_NAME") dn = ldaputils.convert_keyword_to_dn(domain, accountType="domain") try: result = self.conn.search_s( dn, ldap.SCOPE_BASE, "(&(objectClass=mailDomain)(domainName=%s))" % domain, ["domainName", "domainAliasName"], ) return (True, result[0][1].get("domainName", []) + result[0][1].get("domainAliasName", [])) except Exception, e: return (False, ldaputils.getExceptionDesc(e))
def listAccounts(self, domain, cur_page=1): '''List all users.''' if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') domain = str(domain) connutils = connUtils.Utils() if not connutils.is_domain_exists(domain): return (False, 'PERMISSION_DENIED') # Pre-defined. sql_vars = {'domain': domain, } total = 0 try: resultOfTotal = self.conn.select( 'mailbox', vars=sql_vars, what='COUNT(username) AS total', where='domain=$domain', ) if len(resultOfTotal) == 1: total = resultOfTotal[0].total or 0 resultOfRecords = self.conn.select( 'mailbox', vars=sql_vars, # Just query what we need to reduce memory use. what='username,name,quota,employeeid,active', where='domain=$domain', order='username ASC', limit=settings.PAGE_SIZE_LIMIT, offset=(cur_page - 1) * settings.PAGE_SIZE_LIMIT, ) return (True, total, list(resultOfRecords)) except Exception, e: return (False, str(e))
def delete(self, domains=[]): if not isinstance(domains, list): return (False, 'INVALID_DOMAIN_NAME') domains = [str(v).lower() for v in domains if iredutils.is_domain(v) ] if not domains: return (True,) msg = {} for domain in domains: dn = ldaputils.convert_keyword_to_dn(web.safestr(domain), accountType='domain') if dn[0] is False: return dn try: deltree.DelTree(self.conn, dn, ldap.SCOPE_SUBTREE) web.logger(msg="Delete domain: %s." % (domain), domain=domain, event='delete',) except ldap.LDAPError, e: msg[domain] = str(e)
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.is_domain(self.domain): raise web.seeother('/domains?msg=EMPTY_DOMAIN') domainLib = domainlib.Domain() result = domainLib.profile(domain=self.domain) if result[0] is not True: raise web.seeother('/domains?msg=' + web.urlquote(result[1])) else: self.profile = result[1] return web.render( 'pgsql/domain/profile.html', cur_domain=self.domain, profile_type=self.profile_type, profile=self.profile, msg=i.get('msg'), )