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.isDomain(self.cur_domain): # Catchall account. return web.seeother('/profile/domain/catchall/%s' % (self.cur_domain)) if not iredutils.isEmail(self.mail): return web.seeother('/domains?msg=INVALID_USER') if not iredutils.isDomain(self.cur_domain): return 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: return web.seeother('/users/%s?msg=%s' % (self.cur_domain, qr[1])) return web.render( 'mysql/user/profile.html', cur_domain=self.cur_domain, mail=self.mail, profile_type=self.profile_type, profile=self.profile, msg=i.get('msg'), )
def getDomainAdmins(self, domain, mailOnly=False): self.domain = str(domain) if not iredutils.isDomain(self.domain): return (False, 'INVALID_DOMAIN_NAME') try: qr = self.conn.query( ''' SELECT admin.username, admin.name, admin.language, admin.created, admin.active FROM admin LEFT JOIN domain_admins ON (domain_admins.username=admin.username) WHERE domain_admins.domain=%s ''' % web.sqlquote(self.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 add(self, data): self.domain = web.safestr(data.get('domainName', '')).strip().lower() # Get company/organization name. self.cn = data.get('cn', '') # Check domain name. if not iredutils.isDomain(self.domain): return (False, 'INVALID_DOMAIN_NAME') # Check whether domain name already exist (domainName, domainAliasName). connutils = connUtils.Utils() if connutils.isDomainExists(self.domain): return (False, 'ALREADY_EXISTS') # Add domain in database. try: self.conn.insert( 'domain', domain=self.domain, description=self.cn, transport=cfg.general.get('transport', 'dovecot'), created=iredutils.sqlNOW, active='1', ) web.logger(msg="Create domain: %s." % (self.domain), domain=self.domain, event='create',) except Exception, e: return (False, str(e))
def add(self, data): # msg: {key: value} msg = {} self.domain = web.safestr(data.get('domainName', '')).strip().lower() # Check domain name. if not iredutils.isDomain(self.domain): return (False, 'INVALID_DOMAIN_NAME') # Check whether domain name already exist (domainName, domainAliasName). connutils = connUtils.Utils() if connutils.isDomainExists(self.domain): return (False, 'ALREADY_EXISTS') self.dn = ldaputils.convKeywordToDN(self.domain, accountType='domain') 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 delete(self, domains=[]): if not isinstance(domains, types.ListType): return (False, 'INVALID_DOMAIN_NAME') self.domains = [str(v).lower() for v in domains if iredutils.isDomain(v) ] self.sql_domains = web.sqlquote(domains) # Delete domain and related records. try: self.conn.delete('alias', where='domain IN %s' % self.sql_domains) self.conn.delete( 'alias_domain', where='alias_domain IN %s OR target_domain IN %s' % (self.sql_domains,self.sql_domains,), ) self.conn.delete('domain_admins', where='domain IN %s' % self.sql_domains) self.conn.delete('mailbox', where='domain IN %s' % self.sql_domains) self.conn.delete('recipient_bcc_domain', where='domain IN %s' % self.sql_domains) self.conn.delete('recipient_bcc_user', where='domain IN %s' % self.sql_domains) self.conn.delete('sender_bcc_domain', where='domain IN %s' % self.sql_domains) self.conn.delete('sender_bcc_user', where='domain IN %s' % self.sql_domains) # Finally, delete from table `domain` to make sure all related # records were deleted. self.conn.delete('domain', where='domain IN %s' % self.sql_domains) for d in self.domains: web.logger(msg="Delete domain: %s." % (d), domain=d, event='delete',) return (True,) except Exception, e: return (False, str(e))
def isDomainExists(self, domain): if not iredutils.isDomain(domain): return True try: result = self.conn.select( 'domain', what='domain', where='domain = %s' % web.sqlquote(domain), limit=1, ) if len(result) > 0: # Exists. return True result = self.conn.select( 'alias_domain', what='alias_domain', where='alias_domain = %s' % web.sqlquote(domain), limit=1, ) if len(result) > 0: # Alias domain exists. return True else: return False except: # Return True as exist to not allow to create new domain/account. return True
def delete(self, domain, mails=[]): self.domain = str(domain) if not iredutils.isDomain(self.domain): return (False, 'INVALID_DOMAIN_NAME') if not isinstance(mails, types.ListType): return (False, 'INVALID_MAIL') self.mails = [ str(v).lower() for v in mails if iredutils.isEmail(v) and str(v).endswith('@' + self.domain) ] self.sqlMails = web.sqlquote(self.mails) # Delete domain and related records. try: self.conn.delete('mailbox', where='username IN %s' % self.sqlMails) self.conn.delete('alias', where='address IN %s' % self.sqlMails) self.conn.delete('recipient_bcc_user', where='username IN %s' % self.sqlMails) self.conn.delete('sender_bcc_user', where='username IN %s' % self.sqlMails) # TODO Remove email from alias.goto. #self.conn.delete() web.logger( msg="Delete user: %s." % ', '.join(self.mails), domain=self.domain, event='delete', ) return (True, ) 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,) self.accountType = str(accountType) if active is True: self.active = 1 self.action = 'Active' else: self.active = 0 self.action = 'Disable' if self.accountType == 'domain': self.accounts = [str(v) for v in accounts if iredutils.isDomain(v)] try: self.conn.update( 'domain', where='domain IN %s' % (web.sqlquote(self.accounts)), active=self.active, ) except Exception, e: return (False, str(e))
def listAccounts(self, domain, cur_page=1): '''List all users.''' if not iredutils.isDomain(domain): return (False, 'INVALID_DOMAIN_NAME') self.domain = str(domain) # Pre-defined. self.total = 0 try: resultOfTotal = self.conn.select( 'mailbox', what='COUNT(username) AS total', where='domain=%s' % web.sqlquote(self.domain), ) if len(resultOfTotal) == 1: self.total = resultOfTotal[0].total or 0 resultOfRecords = self.conn.select( 'mailbox', # Just query what we need to reduce memory use. what= 'username,name,quota,bytes,messages,employeeid,active,created', where='domain = %s' % web.sqlquote(self.domain), order='username ASC', limit=session['pageSizeLimit'], offset=(cur_page - 1) * session['pageSizeLimit'], ) return (True, self.total, list(resultOfRecords)) except Exception, e: return (False, str(e))
def getAllAliases(self, domain, columns=[],): """Get all aliases under domain. Return (True, [records]).""" self.domain = str(domain) if not iredutils.isDomain(self.domain): raise web.seeother('/domains?msg=INVALID_DOMAIN_NAME') sql_vars = {'domain': self.domain, } try: if columns: result = self.conn.select( 'dbmail_aliases_extra', vars=sql_vars, where='domain=$domain', what=','.join(columns), ) else: result = self.conn.select( 'dbmail_aliases_extra', vars=sql_vars, where='domain=$domain', ) return (True, list(result)) 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.isDomain(v)] try: self.conn.update( 'dbmail_domains', vars={'accounts': accounts, }, where='domain IN $accounts', active=active, ) except Exception, e: return (False, str(e))
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.isEmail(v) and str(v).endswith('@'+self.domain)] self.domaindn = ldaputils.convKeywordToDN(self.domain, accountType='domain') if not iredutils.isDomain(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.convKeywordToDN(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 getUsedBytesMessages(self, domain=None): """Return (messages, bytes)""" if domain is None: resultOfSum = self.conn.query( ''' SELECT SUM(messages) AS messages, SUM(bytes) AS bytes FROM mailbox ''' ) counterOfSum = resultOfSum[0] else: if not iredutils.isDomain(domain): return (0, 0) # Check domain access if self.isDomainAdmin(domain=domain, admin=session.get('username'),): resultOfSum = self.conn.query( ''' SELECT SUM(messages) AS messages, SUM(bytes) AS bytes FROM mailbox WHERE domain = %s ''' % web.sqlquote(domain) ) counterOfSum = resultOfSum[0] else: return (0, 0) return (counterOfSum.messages, counterOfSum.bytes)
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 getManagedDomains(self, admin, domainNameOnly=False, listedOnly=False,): self.admin = web.safestr(admin) if not iredutils.isEmail(self.admin): return (False, 'INCORRECT_USERNAME') self.sql_where = '' self.sql_left_join = '' if listedOnly is True: self.sql_where = 'AND domain_admins.username=%s' % web.sqlquote(self.admin) else: self.sql_left_join = 'OR domain_admins.domain="ALL"' % web.sqlquote(self.admin) 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=%s %s ORDER BY domain_admins.domain """ % (self.sql_left_join, web.sqlquote(self.admin), self.sql_where) ) if domainNameOnly is True: domains = [] for i in result: if iredutils.isDomain(i.domain): domains += [str(i.domain).lower()] return (True, domains) else: return (True, list(result)) except Exception, e: return (False, str(e))
def getDomainAdmins(self, domain, mailOnly=False): self.domain = str(domain) if not iredutils.isDomain(self.domain): return (False, 'INVALID_DOMAIN_NAME') try: qr = self.conn.query( ''' SELECT dbmail_admins.username, dbmail_admins.name, dbmail_admins.language, dbmail_admins.active FROM dbmail_admins LEFT JOIN dbmail_domain_admins ON (dbmail_domain_admins.username=dbmail_admins.username) WHERE dbmail_domain_admins.domain=$domain ''', vars={ 'domain': self.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 add(self, data): self.domain = web.safestr(data.get("domainName", "")).strip().lower() # Get company/organization name. self.cn = data.get("cn", "") # Check domain name. if not iredutils.isDomain(self.domain): return (False, "INVALID_DOMAIN_NAME") # Check whether domain name already exist (domainName, domainAliasName). connutils = connUtils.Utils() if connutils.isDomainExists(self.domain): return (False, "ALREADY_EXISTS") # Add domain in database. try: self.conn.insert( "domain", domain=self.domain, description=self.cn, transport=cfg.general.get("transport", "dovecot"), created=iredutils.sqlNOW, active="1", ) web.logger(msg="Create domain: %s." % (self.domain), domain=self.domain, event="create") except Exception, e: return (False, str(e))
def getDomainAdmins(self, domain, mailOnly=False): self.domain = str(domain) if not iredutils.isDomain(self.domain): return (False, "INVALID_DOMAIN_NAME") try: qr = self.conn.query( """ SELECT admin.username, admin.name, admin.language, admin.created, admin.active FROM admin LEFT JOIN domain_admins ON (domain_admins.username=admin.username) WHERE domain_admins.domain=%s """ % web.sqlquote(self.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 add(self, data): self.domain = web.safestr(data.get('domainName', '')).strip().lower() # Get company/organization name. cn = data.get('cn', '') # Check domain name. if not iredutils.isDomain(self.domain): return (False, 'INVALID_DOMAIN_NAME') # Check whether domain name already exist (domainName, domainAliasName). connutils = connUtils.Utils() if connutils.isDomainExists(self.domain): return (False, 'ALREADY_EXISTS') # Add domain in database. try: self.conn.insert( 'dbmail_domains', domain=self.domain, description=cn, transport=settings.DBMAIL_DEFAULT_DOMAIN_TRANSPORT, ) web.logger( msg="Create domain: %s." % (self.domain), domain=self.domain, event='create', ) 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.isDomain(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/alias/%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])) # Cet total number and allocated quota size of existing users under domain. self.numberOfExistAccounts = 0 resultOfCount = domainLib.getCountsOfExistAccountsUnderDomain( domain=self.cur_domain, accountType='alias', ) if resultOfCount[0] is True: self.numberOfExistAccounts = resultOfCount[1] return web.render( 'dbmail_mysql/alias/create.html', cur_domain=self.cur_domain, allDomains=allDomains, profile=self.profile, numberOfExistAccounts=self.numberOfExistAccounts, numberOfAccounts=2, msg=i.get('msg'), )
def proxyfunc(self, *args, **kw): if 'mail' in kw.keys() and iredutils.isEmail(kw.get('mail')): self.domain = web.safestr(kw['mail']).split('@')[-1] elif 'domain' in kw.keys() and iredutils.isDomain(kw.get('domain')): self.domain = web.safestr(kw['domain']) else: return False self.admin = session.get('username') if not iredutils.isEmail(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', what='username', where='''username=%s AND domain IN %s''' % ( web.sqlquote(self.admin), web.sqlquote([self.domain, 'ALL']), ), ) except Exception, e: result = {} if len(result) != 1: return func(self, *args, **kw) else: return web.seeother('/users' + '?msg=PERMISSION_DENIED&domain=' + self.domain)
def delete(self, domains=[]): if not isinstance(domains, types.ListType): return (False, "INVALID_DOMAIN_NAME") self.domains = [str(v).lower() for v in domains if iredutils.isDomain(v)] self.sql_domains = web.sqlquote(domains) # Delete domain and related records. try: self.conn.delete("alias", where="domain IN %s" % self.sql_domains) self.conn.delete( "alias_domain", where="alias_domain IN %s OR target_domain IN %s" % (self.sql_domains, self.sql_domains) ) self.conn.delete("domain_admins", where="domain IN %s" % self.sql_domains) self.conn.delete("mailbox", where="domain IN %s" % self.sql_domains) self.conn.delete("recipient_bcc_domain", where="domain IN %s" % self.sql_domains) self.conn.delete("recipient_bcc_user", where="domain IN %s" % self.sql_domains) self.conn.delete("sender_bcc_domain", where="domain IN %s" % self.sql_domains) self.conn.delete("sender_bcc_user", where="domain IN %s" % self.sql_domains) # Finally, delete from table `domain` to make sure all related # records were deleted. self.conn.delete("domain", where="domain IN %s" % self.sql_domains) for d in self.domains: web.logger(msg="Delete domain: %s." % (d), domain=d, event="delete") return (True,) except Exception, e: return (False, str(e))
def listAccounts(self, domain='', cur_page=1): '''List all users.''' if not iredutils.isDomain(domain): return (False, 'INVALID_DOMAIN_NAME') self.domain = str(domain) sql_vars = {'domain': self.domain, } try: resultOfTotal = self.conn.select( 'dbmail_aliases_extra', vars=sql_vars, what='COUNT(id) AS total', where='domain=$domain', ) if len(resultOfTotal) == 1: total = resultOfTotal[0].total or 0 resultOfRecords = self.conn.select( 'dbmail_aliases_extra', vars=sql_vars, what='alias, name', where='domain=$domain', limit=settings.PAGE_SIZE_LIMIT, offset=(cur_page - 1) * settings.PAGE_SIZE_LIMIT, ) records = list(resultOfRecords) return (True, total, records) except Exception, e: return (False, str(e))
def getCountsOfExistAccountsUnderDomain(self, domain, accountType='user'): if not iredutils.isDomain(domain): return (False, 'INVALID_DOMAIN_NAME') sql_vars = { 'domain': domain, } if accountType == 'user': try: qr1 = self.conn.select( 'dbmail_users', vars=sql_vars, what='COUNT(user_idnr) AS mailbox_count', where='domain = $domain AND user_idnr > 3', ) mailbox_count = qr1[0].mailbox_count or 0 # Get stored mailbox quota. qr2 = self.conn.select( 'dbmail_users', vars=sql_vars, what='SUM(maxmail_size) AS quota_count', where='domain = $domain AND user_idnr > 3', ) quota_count = qr2[0].quota_count or 0 return (True, mailbox_count, quota_count) except Exception, e: return (False, str(e))
def listAccounts(self, domain, cur_page=1): '''List all users.''' if not iredutils.isDomain(domain): return (False, 'INVALID_DOMAIN_NAME') self.domain = str(domain) # Pre-defined. self.total = 0 try: resultOfTotal = self.conn.select( 'mailbox', what='COUNT(username) AS total', where='domain=%s' % web.sqlquote(self.domain), ) if len(resultOfTotal) == 1: self.total = resultOfTotal[0].total or 0 resultOfRecords = self.conn.select( 'mailbox', # Just query what we need to reduce memory use. what='username,name,quota,bytes,messages,employeeid,active,created', where='domain = %s' % web.sqlquote(self.domain), order='username ASC', limit=session['pageSizeLimit'], offset=(cur_page-1) * session['pageSizeLimit'], ) return (True, self.total, list(resultOfRecords)) except Exception, e: return (False, str(e))
def simpleProfile(self, domain, columns=[]): self.domain = web.safestr(domain) if not iredutils.isDomain(self.domain): return (False, 'INVALID_DOMAIN_NAME') if len(columns) > 0: self.sql_what = ','.join(columns) else: self.sql_what = '*' try: qr = self.conn.select( 'dbmail_domains', vars={ 'domain': self.domain, }, what=self.sql_what, 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 delete(self, domain, mails=[]): self.domain = str(domain) if not iredutils.isDomain(self.domain): return (False, 'INVALID_DOMAIN_NAME') if not isinstance(mails, types.ListType): return (False, 'INVALID_MAIL') self.mails = [str(v).lower() for v in mails if iredutils.isEmail(v) and str(v).endswith('@'+self.domain)] self.sqlMails = web.sqlquote(self.mails) # Delete domain and related records. try: self.conn.delete('mailbox', where='username IN %s' % self.sqlMails) self.conn.delete('alias', where='address IN %s' % self.sqlMails) self.conn.delete('recipient_bcc_user', where='username IN %s' % self.sqlMails) self.conn.delete('sender_bcc_user', where='username IN %s' % self.sqlMails) # TODO Remove email from alias.goto. #self.conn.delete() web.logger( msg="Delete user: %s." % ', '.join(self.mails), domain=self.domain, event='delete', ) return (True,) 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.isDomain(self.domain): return 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( 'mysql/user/list.html', cur_domain=self.domain, cur_page=cur_page, total=total, users=records, msg=web.input().get('msg', None), ) else: return web.seeother('/domains?msg=%s' % 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.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 add(self, domain, data): # Get domain name, username, cn. self.domain = web.safestr(data.get('domainName')).strip().lower() self.username = web.safestr(data.get('listname')).strip().lower() self.mail = self.username + '@' + self.domain if self.domain != domain: return (False, 'PERMISSION_DENIED') if not iredutils.isDomain(self.domain): return (False, 'INVALID_DOMAIN_NAME') if not iredutils.isEmail(self.mail): return (False, 'INVALID_MAIL') # Define columns and values used to insert. columns = {'domain': self.domain, 'alias': self.mail, } # Check account existing. connutils = connUtils.Utils() if connutils.isEmailExists(mail=self.mail): return (False, 'ALREADY_EXISTS') # Get domain profile. domainLib = domainlib.Domain() resultOfDomainProfile = domainLib.profile(domain=self.domain) if resultOfDomainProfile[0] is True: self.domainProfile = resultOfDomainProfile[1] else: return resultOfDomainProfile # Check account limit. adminLib = adminlib.Admin() numberOfExistAccounts = adminLib.getNumberOfManagedAccounts(accountType='alias', domains=[self.domain]) if self.domainProfile.aliases == -1: return (False, 'NOT_ALLOWED') elif self.domainProfile.aliases > 0: if self.domainProfile.aliases <= numberOfExistAccounts: return (False, 'EXCEEDED_DOMAIN_ACCOUNT_LIMIT') # Get display name from <form> columns['name'] = data.get('cn', '') try: # Store new user in required SQL DBs. self.conn.insert( 'dbmail_aliases_extra', **columns ) web.logger(msg="Create mail alias: %s." % (self.mail), domain=self.domain, event='create',) 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.isDomain(domain): return 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=session['pageSizeLimit'], accountType='user', domain=domain, ) accountList = sl.get('accountList', []) if cur_page > sl.get('totalPages'): cur_page = sl.get('totalPages') # Show login date. if cfg.general.get('show_login_date', 'False').lower() in ['true',]: showLoginDate = True else: showLoginDate = False return web.render( 'ldap/user/list.html', cur_page=cur_page, total=sl.get('totalAccounts'), users=accountList, cur_domain=domain, allDomains=allDomains, showLoginDate=showLoginDate, accountUsedQuota={}, msg=i.get('msg'), ) else: return web.seeother('/domains?msg=%s' % 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.isDomain(self.domain): queryDict['domain'] = self.domain if session.get('domainGlobalAdmin') is not True: queryDict['admin'] = session.get('username') else: if iredutils.isEmail(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 getAllAliasDomains(self, domain): self.domain = str(domain) if not iredutils.isDomain(self.domain): return (False, "INVALID_DOMAIN_NAME") try: qr = self.conn.select("alias_domain", where="target_domain=%s" % web.sqlquote(self.domain)) return (True, list(qr)) except Exception, e: return (False, str(e))
def getAllAliasDomains(self, domain): self.domain = str(domain) if not iredutils.isDomain(self.domain): return (False, 'INVALID_DOMAIN_NAME') try: qr = self.conn.select('alias_domain', where='target_domain=%s' % web.sqlquote(self.domain)) return (True, list(qr)) except Exception, e: return (False, str(e))
def getAllAliasDomains( self, domains, namesOnly=False, ): if isinstance(domains, list): domains = [v.lower() for v in domains if iredutils.isDomain(v)] else: domains = str(domains) if not iredutils.isDomain(domains): return (False, 'INVALID_DOMAIN_NAME') else: domains = [domains] try: qr = self.conn.select( 'dbmail_alias_domains', vars={ 'domains': domains, }, where='target_domain IN $domains', ) if namesOnly is True: target_domains = {} for r in qr: target_domain = web.safestr(r.target_domain) if target_domain in target_domains: target_domains[target_domain] += [ web.safestr(r.alias_domain) ] else: target_domains[target_domain] = [ web.safestr(r.alias_domain) ] return (True, target_domains) else: return (True, list(qr)) except Exception, e: return (False, str(e))
def POST(self, domain): i = web.input(_unicode=False, username=[]) self.domain = str(domain) if not iredutils.isDomain(self.domain): return web.seeother('/domains?msg=INVALID_DOMAIN_NAME') self.mails = [ str(v) for v in i.get('username', []) if iredutils.isEmail(v) and str(v).endswith('@' + self.domain) ] self.action = i.get('action', None) msg = i.get('msg', None) userLib = userlib.User() if self.action == 'delete': result = userLib.delete( domain=self.domain, mails=self.mails, ) msg = 'DELETED_SUCCESS' elif self.action == 'disable': result = userLib.enableOrDisableAccount( domain=self.domain, accounts=self.mails, active=False, ) msg = 'DISABLED_SUCCESS' elif self.action == 'enable': result = userLib.enableOrDisableAccount( domain=self.domain, accounts=self.mails, active=True, ) msg = 'ENABLED_SUCCESS' else: result = (False, 'INVALID_ACTION') if result[0] is True: return web.seeother('/users/%s?msg=%s' % ( self.domain, msg, )) else: return web.seeother('/users/%s?msg=%s' % ( self.domain, result[1], ))
def delete(self, domain, mails=[]): self.domain = str(domain) if not iredutils.isDomain(self.domain): return (False, 'INVALID_DOMAIN_NAME') if not isinstance(mails, (list, tuple,)): return (False, 'INVALID_MAIL') self.mails = [str(v).lower() for v in mails if iredutils.isEmail(v) and str(v).endswith('@' + self.domain) ] # Remove alias from domain.defaultuseraliases. # Get domain profile. domainLib = domainlib.Domain() qr = domainLib.simpleProfile(domain=self.domain, columns=['domain', 'defaultuseraliases', ]) if qr[0] is True: self.domainProfile = qr[1] else: return qr self.defaultUserAliases = self.domainProfile.defaultuseraliases.split(',') # Remove from domain.defaultuseraliases. self.newDefaultAliases = [str(v).lower() for v in self.defaultUserAliases if v not in self.mails ] # Delete domain and related records. try: self.conn.delete('dbmail_aliases_extra', where='%s' % web.sqlors('alias = ', self.mails),) self.conn.delete('dbmail_aliases', where='%s' % web.sqlors('alias = ', self.mails),) self.conn.update('dbmail_domains', vars={'domain': self.domain, }, defaultuseraliases=','.join(self.newDefaultAliases), modified=iredutils.getGMTTime(), where='domain = $domain', ) web.logger( msg="Delete mail alias: %s." % ', '.join(self.mails), domain=self.domain, event='delete', ) return (True,) except Exception, e: return (False, str(e))
def profile(self, domain): self.domain = web.safestr(domain) if not iredutils.isDomain(self.domain): return (False, 'INVALID_DOMAIN_NAME') try: qr = self.conn.query( ''' SELECT domain.*, 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.domain AND alias.address <> alias.goto AND alias.address <> %s ) WHERE domain.domain=%s GROUP BY domain.domain, domain.description, domain.aliases, domain.mailboxes, domain.maxquota, domain.quota, domain.transport, domain.backupmx, domain.created, domain.active ORDER BY domain.domain LIMIT 1 ''' % (web.sqlquote(self.domain), web.sqlquote(self.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 profile(self, domain): self.domain = web.safestr(domain) if not iredutils.isDomain(self.domain): return (False, "INVALID_DOMAIN_NAME") try: qr = self.conn.query( """ SELECT domain.*, 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.domain AND alias.address <> alias.goto AND alias.address <> %s ) WHERE domain.domain=%s GROUP BY domain.domain, domain.description, domain.aliases, domain.mailboxes, domain.maxquota, domain.quota, domain.transport, domain.backupmx, domain.created, domain.active ORDER BY domain.domain LIMIT 1 """ % (web.sqlquote(self.domain), web.sqlquote(self.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, types.ListType): return (False, 'INVALID_DOMAIN_NAME') msg = {} for domain in domains: if not iredutils.isDomain(domain): continue dn = ldaputils.convKeywordToDN(web.safestr(domain), accountType='domain') 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 profile(self, domain): self.domain = web.safestr(domain) if not iredutils.isDomain(self.domain): return (False, 'INVALID_DOMAIN_NAME') try: qr = self.conn.query( ''' SELECT dbmail_domains.*, COUNT(dbmail_users.user_idnr) AS mailbox_count, COUNT(dbmail_aliases_extra.id) AS alias_count -- 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, FROM dbmail_domains LEFT JOIN dbmail_domain_admins ON (dbmail_domains.domain = dbmail_domain_admins.domain) -- LEFT JOIN sender_bcc_domain AS sbcc ON (sbcc.domain=dbmail_domains.domain) -- LEFT JOIN recipient_bcc_domain AS rbcc ON (rbcc.domain=dbmail_domains.domain) LEFT JOIN dbmail_users ON (dbmail_domains.domain = dbmail_users.domain) LEFT JOIN dbmail_aliases_extra ON (dbmail_domains.domain = dbmail_aliases_extra.alias) WHERE dbmail_domains.domain=$domain GROUP BY dbmail_domains.domain, dbmail_domains.description, dbmail_domains.aliases, dbmail_domains.mailboxes, dbmail_domains.maxquota, dbmail_domains.quota, dbmail_domains.transport, dbmail_domains.backupmx, dbmail_domains.active ORDER BY dbmail_domains.domain LIMIT 1 ''', vars={ 'domain': self.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 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.isDomain(v)] try: self.conn.delete('dbmail_domains', vars={'accounts': accounts, }, where='domain IN $accounts', ) except Exception, e: return (False, str(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.isEmail(kw.get('mail')): domain = web.safestr(kw['mail']).split('@')[-1] elif 'domain' in kw.keys() and iredutils.isDomain(kw.get('domain')): domain = web.safestr(kw['domain']) else: return (False, 'PERMISSION_DENIED') # Check whether is domain admin. validator = Validator() if validator.isDomainAdmin(domain=domain, admin=session.get('username'),): return func(*args, **kw) else: return (False, 'PERMISSION_DENIED')
def getCountsOfExistAccountsUnderDomain(self, domain, accountType="user"): if not iredutils.isDomain(domain): return (False, "INVALID_DOMAIN_NAME") self.sql_domain = web.sqlquote(domain) if accountType == "user": try: qr1 = self.conn.select( "mailbox", what="COUNT(username) AS mailbox_count", where="domain = %s" % self.sql_domain ) mailbox_count = qr1[0].mailbox_count or 0 qr2 = self.conn.select( "mailbox", what="SUM(quota) AS quota_count", where="domain = %s" % self.sql_domain ) quota_count = qr2[0].quota_count or 0 return (True, mailbox_count, quota_count) except Exception, e: return (False, str(e))
def simpleProfile(self, domain, columns=[]): self.domain = web.safestr(domain) if not iredutils.isDomain(self.domain): return (False, "INVALID_DOMAIN_NAME") if len(columns) > 0: self.sql_what = ",".join(columns) else: self.sql_what = "*" try: qr = self.conn.select("domain", what=self.sql_what, where="domain=%s" % web.sqlquote(self.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 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.isDomain(self.cur_domain): # Catchall account. return web.seeother('/profile/domain/catchall/%s' % (self.cur_domain)) if not iredutils.isEmail(self.mail): return web.seeother('/domains?msg=INVALID_USER') domainAccountSetting = {} userLib = user.User() result = userLib.profile(domain=self.cur_domain, mail=self.mail) if result[0] is True: 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], minPasswordLength=minPasswordLength, maxPasswordLength=maxPasswordLength, msg=i.get('msg', None), ) else: return web.seeother('/users/%s?msg=%s' % (self.cur_domain, result[1]))
def isDomainAdmin(self, domain, admin=session.get('username'),): if not iredutils.isDomain(domain) or not iredutils.isEmail(admin): return False if admin == session.get('username') and session.get('domainGlobalAdmin') is True: return True try: result = self.conn.select( 'domain_admins', what='username', where='domain=%s AND username=%s AND active=1' % ( web.sqlquote(domain), web.sqlquote(admin), ), limit=1, ) if len(result) == 1: return True else: return False except Exception, e: return False
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 not True: return web.seeother('/domains?msg=' + result[1]) else: self.profile = result[1] return web.render( 'mysql/domain/profile.html', cur_domain=self.domain, profile_type=self.profile_type, profile=self.profile, msg=i.get('msg'), )
def getNumberOfManagedAccounts(self, admin=None, accountType='domain', domains=[],): if admin is None: self.admin = session.get('username') else: self.admin = str(admin) if not iredutils.isEmail(self.admin): return 0 self.domains = [] if len(domains) > 0: self.domains = [str(d).lower() for d in domains if iredutils.isDomain(d)] else: qr = self.getManagedDomains(admin=self.admin, domainNameOnly=True) if qr[0] is True: self.domains = qr[1] else: self.domains = [] if accountType == 'domain': try: if self.isGlobalAdmin(self.admin): result = self.conn.select('domain', what='COUNT(domain) AS total',) else: result = self.conn.query( """ SELECT COUNT(domain.domain) AS total FROM domain LEFT JOIN domain_admins ON (domain.domain=domain_admins.domain) WHERE domain_admins.username=%s """ % (web.sqlquote(self.admin)) ) total = result[0].total or 0 return total except Exception, e: pass
def update(self, profile_type, mail, data): self.profile_type = web.safestr(profile_type) self.mail = web.safestr(mail) if session.get('domainGlobalAdmin') is not True and session.get('username') != self.mail: # Don't allow to view/update other admins' profile. return (False, 'PERMISSION_DENIED') self.dn = ldaputils.convKeywordToDN(self.mail, accountType='admin') mod_attrs = [] if self.profile_type == 'general': # Get preferredLanguage. self.lang = web.safestr(data.get('preferredLanguage', 'en_US')) mod_attrs += [(ldap.MOD_REPLACE, 'preferredLanguage', self.lang)] # Get cn. cn = data.get('cn', None) mod_attrs += ldaputils.getSingleModAttr(attr='cn', value=cn, default=self.mail.split('@')[0],) # Get accountStatus. if 'accountStatus' in data.keys(): accountStatus = 'active' else: accountStatus = 'disabled' mod_attrs += [ (ldap.MOD_REPLACE, 'accountStatus', accountStatus) ] try: # Modify profiles. self.conn.modify_s(self.dn, mod_attrs) if session.get('username') == self.mail: session['lang'] = self.lang except ldap.LDAPError, e: return (False, ldaputils.getExceptionDesc(e)) ######################### # Managed domains # if session.get('domainGlobalAdmin') is not True: return (False, 'PERMISSION_DENIED') # Get domains under control. result = self.getManagedDomains(mail=self.mail, attrs=['domainName',]) if result[0] is True: self.managedDomains = [] for d in result[1]: if 'domainName' in d[1].keys(): self.managedDomains += d[1].get('domainName') else: return result # Get domains from web form. self.newmd = [web.safestr(v) for v in data.get('domainName', []) if iredutils.isDomain(v)] # Compare two lists, get domain list which need to remove or add domain admins. self.domainsRemoveAdmins = [str(v) for v in self.managedDomains if v not in self.newmd and iredutils.isDomain(v) ] self.domainsAddAdmins = [str(v) for v in self.newmd if v not in self.managedDomains and iredutils.isDomain(v) ] connutils = connUtils.Utils() for i in self.domainsRemoveAdmins: result = connutils.addOrDelAttrValue( dn=ldaputils.convKeywordToDN(i, accountType='domain'), attr='domainAdmin', value=self.mail, action='delete', ) if result[0] is False: return result for i in self.domainsAddAdmins: result = connutils.addOrDelAttrValue( dn=ldaputils.convKeywordToDN(i, accountType='domain'), attr='domainAdmin', value=self.mail, action='add', ) if result[0] is False: return result return (True,)
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 convKeywordToDN(keyword, accountType="user"): keyword = web.safestr(keyword).strip().replace(" ", "") accountType == web.safestr(accountType) # No matter what account type is, try to get a domain name. domain = keyword.split("@")[-1] # Validate account type. if accountType not in attrs.ACCOUNT_TYPES_ALL: return (False, "INVALID_ACCOUNT_TYPE") # Validate keyword. # Keyword is email address. if accountType in attrs.ACCOUNT_TYPES_EMAIL and not iredutils.isEmail(keyword): return (False, "INVALID_MAIL") # Keyword is domain name. if accountType in attrs.ACCOUNT_TYPES_DOMAIN and not iredutils.isDomain(keyword): return (False, "INVALID_DOMAIN_NAME") # Convert keyword to DN. if accountType == "user": dn = "%s=%s,%s%s=%s,%s" % ( attrs.RDN_USER, keyword, attrs.DN_BETWEEN_USER_AND_DOMAIN, attrs.RDN_DOMAIN, domain, basedn, ) elif accountType == "maillist": dn = "%s=%s,%s%s=%s,%s" % ( attrs.RDN_MAILLIST, keyword, attrs.DN_BETWEEN_MAILLIST_AND_DOMAIN, attrs.RDN_DOMAIN, domain, basedn, ) elif accountType == "maillistExternal": dn = "%s=%s,%s%s=%s,%s" % ( attrs.RDN_MAILLIST_EXTERNAL, keyword, attrs.DN_BETWEEN_MAILLIST_EXTERNAL_AND_DOMAIN, attrs.RDN_DOMAIN, domain, basedn, ) elif accountType == "alias": dn = "%s=%s,%s%s=%s,%s" % ( attrs.RDN_ALIAS, keyword, attrs.DN_BETWEEN_ALIAS_AND_DOMAIN, attrs.RDN_DOMAIN, domain, basedn, ) elif accountType == "admin": dn = "%s=%s,%s" % (attrs.RDN_ADMIN, keyword, domainadmin_dn) elif accountType == "catchall": dn = "%s=@%s,%s%s=%s,%s" % ( attrs.RDN_CATCHALL, domain, attrs.DN_BETWEEN_CATCHALL_AND_DOMAIN, attrs.RDN_DOMAIN, domain, basedn, ) elif accountType == "domain": dn = "%s=%s,%s" % (attrs.RDN_DOMAIN, keyword, basedn) return escape_filter_chars(dn)
domain=self.domain, created=iredutils.sqlNOW, active=self.status, ) except Exception, e: return (False, str(e)) elif self.profile_type == "aliases": if session.get("domainGlobalAdmin") is True: # Delete old records first. try: self.conn.delete("alias_domain", where="target_domain=%s" % web.sqlquote(self.domain)) except Exception, e: return (False, str(e)) # Get domain aliases from web form and store in LDAP. aliasDomains = [str(v).lower() for v in data.get("domainAliasName", []) if iredutils.isDomain(v)] if len(aliasDomains) > 0: v = [] for ad in aliasDomains: v += [ {"alias_domain": ad, "target_domain": self.domain, "created": iredutils.sqlNOW, "active": 1} ] try: self.conn.multiple_insert("alias_domain", values=v) except Exception, e: return (False, str(e)) elif self.profile_type == "advanced": if session.get("domainGlobalAdmin") is True: numberOfUsers = str(data.get("numberOfUsers")) numberOfAliases = str(data.get("numberOfAliases"))
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 if self.domain != domain: return (False, 'PERMISSION_DENIED') if not iredutils.isDomain(self.domain): return (False, 'INVALID_DOMAIN_NAME') # Check account existing. connutils = connUtils.Utils() if connutils.isEmailExists(mail=self.mail): return (False, 'ALREADY_EXISTS') # Get domain profile. domainLib = domainlib.Domain() resultOfDomainProfile = domainLib.profile(domain=self.domain) if resultOfDomainProfile[0] is True: self.domainProfile = resultOfDomainProfile[1] else: return resultOfDomainProfile # Check account limit. adminLib = adminlib.Admin() numberOfExistAccounts = adminLib.getNumberOfManagedAccounts(accountType='user', domains=[self.domain]) if self.domainProfile.mailboxes == 0: # Unlimited. pass elif self.domainProfile.mailboxes <= numberOfExistAccounts: return (False, 'EXCEEDED_DOMAIN_ACCOUNT_LIMIT') # Check spare quota and number of spare account limit. # Get quota from <form> self.mailQuota = str(data.get('mailQuota')).strip() self.defaultUserQuota = self.domainProfile.get('defaultuserquota', 0) if self.mailQuota.isdigit(): self.mailQuota = int(self.mailQuota) else: self.mailQuota = self.defaultUserQuota # Re-calculate mail quota if this domain has limited max quota. if self.domainProfile.maxquota > 0: # Get used quota. qr = domainLib.getAllocatedQuotaSize(domain=self.domain) if qr[0] is True: self.allocatedQuota = qr[1] else: return qr spareQuota = self.domainProfile.maxquota - self.allocatedQuota if spareQuota > 0: if spareQuota < self.mailQuota: self.mailQuota = spareQuota else: # No enough quota. return (False, 'EXCEEDED_DOMAIN_QUOTA_SIZE') # # Get password from <form>. # self.newpw = str(data.get('newpw', '')) self.confirmpw = str(data.get('confirmpw', '')) # Get password length limit from domain profile or global setting. self.minPasswordLength = self.domainProfile.get('minpasswordlength',cfg.general.get('min_passwd_length', '0')) self.maxPasswordLength = self.domainProfile.get('maxpasswordlength', cfg.general.get('max_passwd_length', '0')) resultOfPW = iredutils.verifyNewPasswords( self.newpw, self.confirmpw, min_passwd_length=self.minPasswordLength, max_passwd_length=self.maxPasswordLength, ) if resultOfPW[0] is True: self.passwd = iredutils.getSQLPassword(resultOfPW[1]) else: return resultOfPW # Get display name from <form> self.cn = data.get('cn', '') # Assign new user to default mail aliases. assignedAliases = [str(v).lower() for v in str(self.domainProfile.defaultuseraliases).split(',') if iredutils.isEmail(v) ] try: # Store new user in SQL db. self.conn.insert( 'mailbox', domain=self.domain, username=self.mail, password=self.passwd, name=self.cn, maildir=iredutils.setMailMessageStore(self.mail), quota=self.mailQuota, created=iredutils.sqlNOW, active='1', local_part=self.username, ) # Assign new user to default mail aliases. if len(assignedAliases) > 0: for ali in assignedAliases: try: self.conn.query( ''' UPDATE alias SET goto=CONCAT(goto, %s) WHERE address=%s AND domain=%s ''' % ( web.sqlquote(','+self.mail), web.sqlquote(ali), web.sqlquote(self.domain), ) ) except: pass # Create an alias account: address=goto. self.conn.insert( 'alias', address=self.mail, goto=self.mail, domain=self.domain, created=iredutils.sqlNOW, active='1', ) web.logger(msg="Create user: %s." % (self.mail), domain=self.domain, event='create',) return (True,) except Exception, e: return (False, str(e))
def ldif_mailuser(domain, username, cn, passwd, quota=0, aliasDomains=[], groups=[],storageBaseDirectory=None,): domain = str(domain).lower() username = ldaputils.removeSpace(str(username)).lower() mail = username + '@' + domain if storageBaseDirectory is None: tmpStorageBaseDirectory = cfg.general.get('storage_base_directory').lower() else: tmpStorageBaseDirectory = storageBaseDirectory splitedSBD = tmpStorageBaseDirectory.rstrip('/').split('/') storageNode = splitedSBD.pop() storageBaseDirectory = '/'.join(splitedSBD) mailMessageStore = storageNode + '/' + iredutils.setMailMessageStore(mail) homeDirectory = storageBaseDirectory + '/' + mailMessageStore # Generate basic LDIF. ldif = [ ('objectClass', ['inetOrgPerson', 'mailUser', 'shadowAccount', 'amavisAccount',]), ('mail', [mail]), ('userPassword', [str(passwd)]), ('sn', [username]), ('uid', [username]), ('storageBaseDirectory', [storageBaseDirectory]), ('mailMessageStore', [mailMessageStore]), ('homeDirectory', [homeDirectory]), ('accountStatus', ['active']), ('enabledService', ['mail', 'deliver', 'lda', 'smtp', 'smtpsecured', 'pop3', 'pop3secured', 'imap', 'imapsecured', 'managesieve', 'managesievesecured', # ManageService name In dovecot-1.2. 'sieve', 'sievesecured', 'forward', 'senderbcc', 'recipientbcc', 'internal', 'shadowaddress', 'displayedInGlobalAddressBook',]), # Amavisd integration. ('amavisLocal', ['TRUE']), ] # Append @shadowAddress. shadowAddresses = [] for d in aliasDomains: if iredutils.isDomain(d): shadowAddresses += [username + '@' + d] if len(shadowAddresses) > 0: ldif += [('shadowAddress', shadowAddresses)] # Append quota. No 'mailQuota' attribute means unlimited. quota = str(quota).strip() if quota.isdigit(): quota = int(quota) * 1024 * 1024 ldif += [('mailQuota', [str(quota)])] # Append cn. ldif += ldaputils.getLdifOfSingleAttr(attr='cn', value=cn, default=username,) # Append groups. if isinstance(groups, list) and len(groups) >= 1: # Remove duplicate items. grps = set() for g in groups: grps.update([str(g).strip()]) ldif += [('memberOfGroup', list(grps))] return ldif