def add(self, data): self.cn = data.get('cn', '') self.mail = web.safestr(data.get('mail')).strip().lower() if not iredutils.is_email(self.mail): return (False, 'INVALID_MAIL') # Check admin exist. connutils = connUtils.Utils() if connutils.isAdminExists(self.mail): return (False, 'ALREADY_EXISTS') # Get domainGlobalAdmin setting. self.domainGlobalAdmin = web.safestr(data.get('domainGlobalAdmin', 'no')) if self.domainGlobalAdmin not in ['yes', 'no', ]: self.domainGlobalAdmin = 'no' # Get language setting. self.preferredLanguage = web.safestr(data.get('preferredLanguage', 'en_US')) # Get new password. self.newpw = web.safestr(data.get('newpw')) self.confirmpw = web.safestr(data.get('confirmpw')) result = iredutils.verify_new_password(self.newpw, self.confirmpw) if result[0] is True: self.passwd = result[1] else: return result try: self.conn.insert( 'admin', username=self.mail, name=self.cn, password=iredutils.generate_password_hash(self.passwd), language=self.preferredLanguage, created=iredutils.get_gmttime(), active='1', ) if self.domainGlobalAdmin == 'yes': self.conn.insert( 'domain_admins', username=self.mail, domain='ALL', created=iredutils.get_gmttime(), active='1', ) web.logger(msg="Create admin: %s." % (self.mail), event='create',) return (True,) except Exception, 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 update(self, domain, profile_type, data,): profile_type = str(profile_type) domain = str(domain) # Pre-defined update key:value. updates = {'modified': iredutils.get_gmttime(), } sql_vars = {'domain': domain, } if profile_type == 'general': # Get name cn = data.get('cn', '') updates['description'] = cn if session.get('domainGlobalAdmin') is True: # Get account status if 'accountStatus' in data.keys(): updates['active'] = 1 else: updates['active'] = 0 # Update SQL db with columns: maxquota, active. try: self.conn.update( 'domain', vars=sql_vars, where='domain=$domain', **updates ) except Exception, 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 log_activity(msg, admin="", domain="", username="", event="", loglevel="info"): try: if not admin: admin = session.get("username") msg = str(msg) # Prepend '[API]' in log message try: if web.ctx.fullpath.startswith("/api/"): msg = "[API] " + msg except: pass web.conn_iredadmin.insert( "log", admin=str(admin), domain=str(domain), username=str(username), loglevel=str(loglevel), event=str(event), msg=msg, ip=str(session.ip), timestamp=iredutils.get_gmttime(), ) except: pass return None
def update(mail, profile_type, form, conn=None): mail = str(mail).lower() # Don't allow to view/update other admins' profile. if mail != session.get('username') and not session.get('is_global_admin'): return (False, 'PERMISSION_DENIED') sql_vars = {'username': mail} if not conn: _wrap = SQLWrap() conn = _wrap.conn params = {} if profile_type == 'general': # Name, preferred language params['name'] = form.get('cn', '') params['language'] = form_utils.get_language(form) # Update account status params['active'] = 0 if 'accountStatus' in form: params['active'] = 1 elif profile_type == 'password': newpw = web.safestr(form.get('newpw', '')) confirmpw = web.safestr(form.get('confirmpw', '')) # Verify new passwords. qr = iredpwd.verify_new_password(newpw=newpw, confirmpw=confirmpw) if qr[0] is True: passwd = iredpwd.generate_password_hash(qr[1]) params['password'] = passwd params['passwordlastchange'] = iredutils.get_gmttime() else: return qr if params: try: conn.update('admin', vars=sql_vars, where='username=$username', **params) except Exception as e: log_traceback() if 'password' in params: raise web.seeother('/profile/admin/password/{}?msg={}'.format( mail, web.urlquote(e))) else: raise web.seeother('/profile/admin/general/{}?msg={}'.format( mail, web.urlquote(e))) return (True, )
def log_to_iredadmin(msg, event, admin='', loglevel='info'): conn = get_db_conn('iredadmin') try: conn.insert('log', admin=admin, event=event, loglevel=loglevel, msg=str(msg), ip='127.0.0.1', timestamp=iredutils.get_gmttime()) except: pass return None
def add(form, conn=None): domain = form_utils.get_domain_name(form) # Check domain name. if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN_NAME') if not conn: _wrap = SQLWrap() conn = _wrap.conn # Check whether domain name already exist (domainName, domainAliasName). if sql_lib_general.is_domain_exists(domain=domain, conn=conn): return (False, 'ALREADY_EXISTS') params = { 'domain': domain, 'transport': settings.default_mta_transport, 'active': 1, 'created': iredutils.get_gmttime(), } # Name kv = form_utils.get_form_dict(form=form, input_name='cn', key_name='description') params.update(kv) # Add domain in database. try: conn.insert('domain', **params) log_activity(msg="New domain: %s." % (domain), domain=domain, event='create') # If it's a normal domain admin with permission to create new domain, # assign current admin as admin of this newly created domain. if session.get('create_new_domains'): qr = assign_admins_to_domain(domain=domain, admins=[session.get('username')], conn=conn) if not qr[0]: return qr except Exception as e: return (False, repr(e)) return (True, )
def log_activity(msg, admin="", domain="", username="", event="", loglevel="info"): try: if not admin: if session.get("is_global_admin_api"): admin = "API_KEY-" + session.get("global_admin_api_key") else: admin = session.get("username") msg = str(msg) # Prepend '[API]' in log message try: if web.ctx.fullpath.startswith("/api/"): msg = "[API] " + msg except: pass web.conn_iredadmin.insert( "log", admin=str(admin), domain=str(domain), username=str(username), loglevel=str(loglevel), event=str(event), msg=msg, ip=str(session.ip), timestamp=iredutils.get_gmttime(), ) if loglevel == "info": logger.info("{0} admin={1}, domain={2}, username={3}, event={4}, " "ip={5}".format(msg, admin, domain, username, event, session.ip)) elif loglevel == "error": logger.error("{0} admin={1}, domain={2}, username={3}, event={4}, " "ip={5}".format(msg, admin, domain, username, event, session.ip)) except: pass return None
def update(self, profile_type, mail, data): self.profile_type = web.safestr(profile_type) self.mail = str(mail).lower() self.domain = self.mail.split('@', 1)[-1] # Pre-defined update key:value. updates = {'modified': iredutils.get_gmttime()} if self.profile_type == 'general': # Get settings of domain admin and global admin managed_domain='' if 'domainadmin' in data: # isadmin=1 updates['isadmin'] = 1 managed_domain=self.domain else: updates['isadmin'] = 0 if session.get('domainGlobalAdmin'): if 'domainGlobalAdmin' in data: updates['isadmin'] = 1 updates['isglobaladmin'] = 1 managed_domain='ALL' else: updates['isglobaladmin'] = 0 # Delete records in domain_admins first self.conn.delete('domain_admins', vars={'username': self.mail}, where='username=$username', ) if updates.get('isadmin') == 1: try: self.conn.insert('domain_admins', username=self.mail, domain=managed_domain, created=iredutils.get_gmttime(), active=1, ) except: pass # Get name cn = data.get('cn', '') updates['name'] = cn # Get preferred language: short lang code. e.g. en_US, de_DE. preferred_lang = web.safestr(data.get('preferredLanguage', 'en_US')) # Must be equal to or less than 5 characters. if len(preferred_lang) > 5: preferred_lang = preferred_lang[:5] updates['language'] = preferred_lang # Update language immediately. if session.get('username') == self.mail and \ session.get('lang', 'en_US') != preferred_lang: session['lang'] = preferred_lang # Get account status if 'accountStatus' in data.keys(): updates['active'] = 1 else: updates['active'] = 0 # Get mail quota size. mailQuota = str(data.get('mailQuota')) if mailQuota.isdigit(): updates['quota'] = int(mailQuota) # Get employee id. employeeNumber = data.get('employeeNumber', '') updates['employeeid'] = employeeNumber elif self.profile_type == 'password': newpw = str(data.get('newpw', '')) confirmpw = str(data.get('confirmpw', '')) # Verify new passwords. qr = iredutils.verify_new_password(newpw, confirmpw) if qr[0] is True: pwscheme = None if 'storePasswordInPlainText' in data and settings.STORE_PASSWORD_IN_PLAIN_TEXT: pwscheme = 'PLAIN' passwd = iredutils.generate_password_for_sql_mail_account(qr[1], pwscheme=pwscheme) else: return qr # Hash/encrypt new password. updates['password'] = passwd # Update password last change date in column: passwordlastchange. # # Old iRedMail version doesn't have column mailbox.passwordlastchange, # so we update it with a seperate SQL command with exception handle. try: self.conn.update( 'mailbox', vars={'username': self.mail, }, where='username=$username', passwordlastchange=iredutils.get_gmttime(), ) except: pass else: return (True,) # Update SQL db try: self.conn.update( 'mailbox', vars={'username': self.mail, 'domain': self.domain, }, where='username=$username AND domain=$domain', **updates ) # Update session immediately after updating SQL. if profile_type == 'general': if not 'domainGlobalAdmin' in data and \ session.get('username') == self.mail: session['domainGlobalAdmin'] = False return (True,) except Exception, e: return (False, str(e))
def add_user_from_form(domain, form, conn=None): # Get domain name, username, cn. mail_domain = form_utils.get_domain_name(form) mail_username = form.get('username') if mail_username: mail_username = web.safestr(mail_username).strip().lower() else: return (False, 'INVALID_ACCOUNT') mail = mail_username + '@' + mail_domain if mail_domain != domain: return (False, 'PERMISSION_DENIED') if not iredutils.is_auth_email(mail): return (False, 'INVALID_MAIL') if not conn: _wrap = SQLWrap() conn = _wrap.conn # Check account existing. if sql_lib_general.is_email_exists(mail=mail, conn=conn): return (False, 'ALREADY_EXISTS') # Get domain profile. qr_profile = sql_lib_domain.profile(conn=conn, domain=domain) if qr_profile[0] is True: domain_profile = qr_profile[1] domain_settings = sqlutils.account_settings_string_to_dict( domain_profile['settings']) else: return qr_profile # Check account limit. num_exist_accounts = sql_lib_admin.num_managed_users(conn=conn, domains=[domain]) if domain_profile.mailboxes == -1: return (False, 'NOT_ALLOWED') elif domain_profile.mailboxes > 0: if domain_profile.mailboxes <= num_exist_accounts: return (False, 'EXCEEDED_DOMAIN_ACCOUNT_LIMIT') # Get quota from <form> quota = str(form.get('mailQuota', 0)).strip() try: quota = int(quota) except: quota = 0 # # Get password from <form>. # pw_hash = form.get('password_hash', '') newpw = web.safestr(form.get('newpw', '')) confirmpw = web.safestr(form.get('confirmpw', '')) if pw_hash: if not iredpwd.is_supported_password_scheme(pw_hash): return (False, 'INVALID_PASSWORD_SCHEME') passwd = pw_hash else: # Get password length limit from domain profile or global setting. min_passwd_length = domain_settings.get('min_passwd_length', 0) max_passwd_length = domain_settings.get('max_passwd_length', 0) qr_pw = iredpwd.verify_new_password( newpw, confirmpw, min_passwd_length=min_passwd_length, max_passwd_length=max_passwd_length) if qr_pw[0] is True: pwscheme = None if 'store_password_in_plain_text' in form and settings.STORE_PASSWORD_IN_PLAIN_TEXT: pwscheme = 'PLAIN' passwd = iredpwd.generate_password_hash(qr_pw[1], pwscheme=pwscheme) else: return qr_pw # Get display name from <form> cn = form_utils.get_single_value(form, input_name='cn', default_value='') # Get preferred language. preferred_language = form_utils.get_language(form) if preferred_language not in iredutils.get_language_maps(): preferred_language = '' # Get storage base directory. _storage_base_directory = settings.storage_base_directory splited_sbd = _storage_base_directory.rstrip('/').split('/') storage_node = splited_sbd.pop() storage_base_directory = '/'.join(splited_sbd) maildir = iredutils.generate_maildir_path(mail) # Read full maildir path from web form - from RESTful API. mailbox_maildir = form.get('maildir', '').lower().rstrip('/') if mailbox_maildir and os.path.isabs(mailbox_maildir): # Split storageBaseDirectory and storageNode _splited = mailbox_maildir.rstrip('/').split('/') storage_base_directory = '/' + _splited[0] storage_node = _splited[1] maildir = '/'.join(_splited[2:]) record = { 'domain': domain, 'username': mail, 'password': passwd, 'name': cn, 'quota': quota, 'storagebasedirectory': storage_base_directory, 'storagenode': storage_node, 'maildir': maildir, 'language': preferred_language, 'passwordlastchange': iredutils.get_gmttime(), 'created': iredutils.get_gmttime(), 'active': 1 } # Get settings from SQL db. db_settings = iredutils.get_settings_from_db() # Get mailbox format and folder. _mailbox_format = form.get('mailboxFormat', db_settings['mailbox_format']).lower() _mailbox_folder = form.get('mailboxFolder', db_settings['mailbox_folder']) if iredutils.is_valid_mailbox_format(_mailbox_format): record['mailboxformat'] = _mailbox_format if iredutils.is_valid_mailbox_folder(_mailbox_folder): record['mailboxfolder'] = _mailbox_folder # Always store plain password in another attribute. if settings.STORE_PLAIN_PASSWORD_IN_ADDITIONAL_ATTR: record[settings.STORE_PLAIN_PASSWORD_IN_ADDITIONAL_ATTR] = newpw # Set disabled mail services. disabled_mail_services = domain_settings.get('disabled_mail_services', []) for srv in disabled_mail_services: record['enable' + srv] = 0 # globally disabled mail services for srv in settings.ADDITIONAL_DISABLED_USER_SERVICES: record['enable' + srv] = 0 # globally enabled mail services for srv in settings.ADDITIONAL_ENABLED_USER_SERVICES: record['enable' + srv] = 1 try: # Store new user in SQL db. conn.insert('mailbox', **record) # Create an entry in `vmail.forwardings` with `address=forwarding` conn.insert('forwardings', address=mail, forwarding=mail, domain=domain, dest_domain=domain, is_forwarding=1, active=1) log_activity(msg="Create user: %s." % (mail), domain=domain, event='create') return (True, ) except Exception as e: return (False, repr(e))
def add(self, domain, data): # Get domain name, username, cn. self.domain = web.safestr(data.get('domainName')).strip().lower() mail_local_part = web.safestr(data.get('username')).strip().lower() self.mail = mail_local_part + '@' + self.domain if not iredutils.is_domain(self.domain): return (False, 'INVALID_DOMAIN_NAME') if self.domain != domain: return (False, 'PERMISSION_DENIED') if not iredutils.is_email(self.mail): return (False, 'INVALID_MAIL') # Check account existing. connutils = connUtils.Utils() if connutils.is_email_exists(mail=self.mail): return (False, 'ALREADY_EXISTS') # Get domain profile. domainLib = domainlib.Domain() resultOfDomainProfile = domainLib.profile(domain=self.domain) if resultOfDomainProfile[0] is True: domainProfile = resultOfDomainProfile[1] else: return resultOfDomainProfile # Check account limit. adminLib = adminlib.Admin() numberOfExistAccounts = adminLib.getNumberOfManagedAccounts(accountType='user', domains=[self.domain]) if domainProfile.mailboxes == -1: return (False, 'NOT_ALLOWED') elif domainProfile.mailboxes > 0: if domainProfile.mailboxes <= numberOfExistAccounts: return (False, 'EXCEEDED_DOMAIN_ACCOUNT_LIMIT') # Check spare quota and number of spare account limit. # Get quota from <form> mailQuota = str(data.get('mailQuota')).strip() if mailQuota.isdigit(): mailQuota = int(mailQuota) else: mailQuota = 0 # Re-calculate mail quota if this domain has limited max quota. if domainProfile.maxquota > 0: # Get used quota. qr = domainLib.getAllocatedQuotaSize(domain=self.domain) if qr[0] is True: allocatedQuota = qr[1] else: return qr spareQuota = domainProfile.maxquota - allocatedQuota if spareQuota > 0: if spareQuota < mailQuota: mailQuota = spareQuota else: # No enough quota. return (False, 'EXCEEDED_DOMAIN_QUOTA_SIZE') # # Get password from <form>. # newpw = web.safestr(data.get('newpw', '')) confirmpw = web.safestr(data.get('confirmpw', '')) resultOfPW = iredutils.verify_new_password( newpw, confirmpw, min_passwd_length=settings.min_passwd_length, max_passwd_length=settings.max_passwd_length, ) if resultOfPW[0] is True: pwscheme = None if 'storePasswordInPlainText' in data and settings.STORE_PASSWORD_IN_PLAIN_TEXT: pwscheme = 'PLAIN' passwd = iredutils.generate_password_for_sql_mail_account(resultOfPW[1], pwscheme=pwscheme) else: return resultOfPW # Get display name from <form> cn = data.get('cn', '') # Get storage base directory. tmpStorageBaseDirectory = settings.storage_base_directory.lower() splitedSBD = tmpStorageBaseDirectory.rstrip('/').split('/') storageNode = splitedSBD.pop() storageBaseDirectory = '/'.join(splitedSBD) try: # Store new user in SQL db. self.conn.insert( 'mailbox', domain=self.domain, username=self.mail, password=passwd, name=cn, maildir=iredutils.generate_maildir_path(self.mail), quota=mailQuota, storagebasedirectory=storageBaseDirectory, storagenode=storageNode, created=iredutils.get_gmttime(), active='1', local_part=mail_local_part, ) # Create an alias account: address=goto. self.conn.insert( 'alias', address=self.mail, goto=self.mail, domain=self.domain, created=iredutils.get_gmttime(), 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 update(self, profile_type, mail, data): self.profile_type = web.safestr(profile_type) self.mail = str(mail).lower() self.domain = self.mail.split('@', 1)[-1] # Pre-defined update key:value. updates = {'modified': iredutils.get_gmttime()} if self.profile_type == 'general': # Get settings of domain admin and global admin managed_domain = '' if 'domainadmin' in data: # isadmin=1 updates['isadmin'] = 1 managed_domain = self.domain else: updates['isadmin'] = 0 if session.get('domainGlobalAdmin'): if 'domainGlobalAdmin' in data: updates['isadmin'] = 1 updates['isglobaladmin'] = 1 managed_domain = 'ALL' else: updates['isglobaladmin'] = 0 # Delete records in domain_admins first self.conn.delete('domain_admins', vars={'username': self.mail}, where='username=$username') if updates.get('isadmin') == 1: try: self.conn.insert('domain_admins', username=self.mail, domain=managed_domain, created=iredutils.get_gmttime(), active=1) except: pass # Get name cn = data.get('cn', '') updates['name'] = cn # Get preferred language: short lang code. e.g. en_US, de_DE. preferred_lang = web.safestr(data.get('preferredLanguage', 'en_US')) # Must be equal to or less than 5 characters. if len(preferred_lang) > 5: preferred_lang = preferred_lang[:5] updates['language'] = preferred_lang # Update language immediately. if session.get('username') == self.mail and \ session.get('lang', 'en_US') != preferred_lang: session['lang'] = preferred_lang # Get account status if 'accountStatus' in list(data.keys()): updates['active'] = 1 else: updates['active'] = 0 # Get mail quota size. mailQuota = str(data.get('mailQuota')) if mailQuota.isdigit(): updates['quota'] = int(mailQuota) # Get employee id. employeeNumber = data.get('employeeNumber', '') updates['employeeid'] = employeeNumber elif self.profile_type == 'password': newpw = str(data.get('newpw', '')) confirmpw = str(data.get('confirmpw', '')) # Verify new passwords. qr = iredutils.verify_new_password(newpw, confirmpw) if qr[0] is True: pwscheme = None if 'storePasswordInPlainText' in data and settings.STORE_PASSWORD_IN_PLAIN_TEXT: pwscheme = 'PLAIN' passwd = iredutils.generate_password_hash(qr[1], pwscheme=pwscheme) else: return qr # Hash/encrypt new password. updates['password'] = passwd # Update password last change date in column: passwordlastchange. # # Old iRedMail version doesn't have column mailbox.passwordlastchange, # so we update it with a seperate SQL command with exception handle. try: self.conn.update( 'mailbox', vars={ 'username': self.mail, }, where='username=$username', passwordlastchange=iredutils.get_gmttime(), ) except: pass else: return (True, ) # Update SQL db try: self.conn.update('mailbox', vars={ 'username': self.mail, 'domain': self.domain, }, where='username=$username AND domain=$domain', **updates) # Update session immediately after updating SQL. if profile_type == 'general': if 'domainGlobalAdmin' not in data and \ session.get('username') == self.mail: session['domainGlobalAdmin'] = False return (True, ) except Exception as e: return (False, str(e))
def add_admin_from_form(form, conn=None): mail = web.safestr(form.get('mail')).strip().lower() if not iredutils.is_email(mail): return (False, 'INVALID_MAIL') # Get new password. newpw = web.safestr(form.get('newpw')) confirmpw = web.safestr(form.get('confirmpw')) qr = iredpwd.verify_new_password(newpw=newpw, confirmpw=confirmpw) if qr[0] is True: passwd = qr[1] else: return qr if not conn: _wrap = SQLWrap() conn = _wrap.conn # Check local domain domain = mail.split('@', 1)[-1] if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN') if sql_lib_general.is_domain_exists(domain=domain, conn=conn): return (False, 'CAN_NOT_BE_LOCAL_DOMAIN') # Check admin exist. if is_admin_exists(conn=conn, admin=mail): return (False, 'ALREADY_EXISTS') # Name, language cn = form.get('cn', '') lang = form_utils.get_language(form) _status = form_utils.get_single_value(form=form, input_name='accountStatus', default_value='active') if _status == 'active': _status = 1 else: _status = 0 try: conn.insert('admin', username=mail, name=cn, password=iredpwd.generate_password_hash(passwd), language=lang, created=iredutils.get_gmttime(), active=_status) conn.insert('domain_admins', username=mail, domain='ALL', created=iredutils.get_gmttime(), active='1') log_activity(msg="Create admin: %s." % (mail), event='create') return (True, ) except Exception as e: log_traceback() return (False, repr(e))
def update(conn, mail, profile_type, form): profile_type = web.safestr(profile_type) mail = str(mail).lower() domain = mail.split('@', 1)[-1] qr = sql_lib_domain.simple_profile(conn=conn, domain=domain, columns=['maxquota', 'settings']) if not qr[0]: return qr domain_profile = qr[1] del qr domain_settings = sqlutils.account_settings_string_to_dict( domain_profile.get('settings', '')) disabled_user_profiles = domain_settings.get('disabled_user_profiles', []) if not session.get('is_global_admin'): if profile_type in disabled_user_profiles: return (False, 'PERMISSION_DENIED') # Pre-defined update key:value pairs updates = {'modified': iredutils.get_gmttime()} if profile_type == 'general': # Get name updates['name'] = form.get('cn', '') # Get preferred language: short lang code. e.g. en_US, de_DE. preferred_language = form_utils.get_language(form) if preferred_language in iredutils.get_language_maps(): updates['language'] = preferred_language else: updates['language'] = '' tz_name = form_utils.get_timezone(form) if tz_name: sql_lib_general.update_user_settings( conn=conn, mail=mail, new_settings={'timezone': tz_name}) if session['username'] == mail: session['timezone'] = TIMEZONES[tz_name] else: sql_lib_general.update_user_settings(conn=conn, mail=mail, removed_settings=['timezone']) # Update language immediately. if session.get('username') == mail and \ session.get('lang', 'en_US') != preferred_language: session['lang'] = preferred_language # check account status updates['active'] = 0 if 'accountStatus' in form: updates['active'] = 1 # Update account status in table `alias` immediately try: conn.update('forwardings', vars={'address': mail}, where='address=$address OR forwarding=$address', active=updates['active']) except: pass # Get mail quota size. mailQuota = str(form.get('mailQuota')) if mailQuota.isdigit(): mailQuota = int(mailQuota) else: mailQuota = 0 updates['quota'] = mailQuota updates['employeeid'] = form.get('employeeNumber', '') elif profile_type == 'password': newpw = web.safestr(form.get('newpw', '')) confirmpw = web.safestr(form.get('confirmpw', '')) # Get password length limit from domain profile or global setting. min_passwd_length = domain_settings.get('min_passwd_length', 0) max_passwd_length = domain_settings.get('max_passwd_length', 0) # Verify new passwords. qr = iredpwd.verify_new_password(newpw=newpw, confirmpw=confirmpw, min_passwd_length=min_passwd_length, max_passwd_length=max_passwd_length) if qr[0] is True: pwscheme = None if 'store_password_in_plain_text' in form and settings.STORE_PASSWORD_IN_PLAIN_TEXT: pwscheme = 'PLAIN' passwd = iredpwd.generate_password_hash(qr[1], pwscheme=pwscheme) else: return qr # Hash/encrypt new password. updates['password'] = passwd updates['passwordlastchange'] = iredutils.get_gmttime() # Store plain password in another attribute. if settings.STORE_PLAIN_PASSWORD_IN_ADDITIONAL_ATTR: updates[settings.STORE_PLAIN_PASSWORD_IN_ADDITIONAL_ATTR] = newpw else: return (True, ) # Update SQL db try: conn.update('mailbox', vars={'username': mail}, where='username=$username', **updates) log_activity(msg="Update user profile ({}): {}.".format( profile_type, mail), admin=session.get('username'), username=mail, domain=domain, event='update') return (True, {}) except Exception as e: return (False, repr(e))
def add(self, domain, data): # Get domain name, username, cn. self.domain = web.safestr(data.get('domainName')).strip().lower() mail_local_part = web.safestr(data.get('username')).strip().lower() self.mail = mail_local_part + '@' + self.domain if not iredutils.is_domain(self.domain): return (False, 'INVALID_DOMAIN_NAME') if self.domain != domain: return (False, 'PERMISSION_DENIED') if not iredutils.is_email(self.mail): return (False, 'INVALID_MAIL') # Check account existing. connutils = connUtils.Utils() if connutils.is_email_exists(mail=self.mail): return (False, 'ALREADY_EXISTS') # Get domain profile. domainLib = domainlib.Domain() resultOfDomainProfile = domainLib.profile(domain=self.domain) if resultOfDomainProfile[0] is True: domainProfile = resultOfDomainProfile[1] else: return resultOfDomainProfile # Check account limit. adminLib = adminlib.Admin() numberOfExistAccounts = adminLib.getNumberOfManagedAccounts( accountType='user', domains=[self.domain]) if domainProfile.mailboxes == -1: return (False, 'NOT_ALLOWED') elif domainProfile.mailboxes > 0: if domainProfile.mailboxes <= numberOfExistAccounts: return (False, 'EXCEEDED_DOMAIN_ACCOUNT_LIMIT') # Check spare quota and number of spare account limit. # Get quota from <form> mailQuota = str(data.get('mailQuota')).strip() if mailQuota.isdigit(): mailQuota = int(mailQuota) else: mailQuota = 0 # Re-calculate mail quota if this domain has limited max quota. if domainProfile.maxquota > 0: # Get used quota. qr = domainLib.getAllocatedQuotaSize(domain=self.domain) if qr[0] is True: allocatedQuota = qr[1] else: return qr spareQuota = domainProfile.maxquota - allocatedQuota if spareQuota > 0: if spareQuota < mailQuota: mailQuota = spareQuota else: # No enough quota. return (False, 'EXCEEDED_DOMAIN_QUOTA_SIZE') # # Get password from <form>. # newpw = web.safestr(data.get('newpw', '')) confirmpw = web.safestr(data.get('confirmpw', '')) resultOfPW = iredutils.verify_new_password( newpw, confirmpw, min_passwd_length=settings.min_passwd_length, max_passwd_length=settings.max_passwd_length, ) if resultOfPW[0] is True: pwscheme = None if 'storePasswordInPlainText' in data and settings.STORE_PASSWORD_IN_PLAIN_TEXT: pwscheme = 'PLAIN' passwd = iredutils.generate_password_hash(resultOfPW[1], pwscheme=pwscheme) else: return resultOfPW # Get display name from <form> cn = data.get('cn', '') # Get storage base directory. tmpStorageBaseDirectory = settings.storage_base_directory.lower() splitedSBD = tmpStorageBaseDirectory.rstrip('/').split('/') storageNode = splitedSBD.pop() storageBaseDirectory = '/'.join(splitedSBD) try: # Store new user in SQL db. self.conn.insert( 'mailbox', domain=self.domain, username=self.mail, password=passwd, name=cn, maildir=iredutils.generate_maildir_path(self.mail), quota=mailQuota, storagebasedirectory=storageBaseDirectory, storagenode=storageNode, mailboxformat=settings.MAILBOX_FORMAT, created=iredutils.get_gmttime(), active='1', ) self.conn.insert('forwardings', address=self.mail, forwarding=self.mail, domain=self.domain, is_forwarding=1) web.logger( msg="Create user: %s." % (self.mail), domain=self.domain, event='create', ) return (True, ) except Exception as e: return (False, str(e))
self.newpw = web.safestr(data.get('newpw', '')) self.confirmpw = web.safestr(data.get('confirmpw', '')) # Verify new passwords. qr = iredutils.verify_new_password(self.newpw, self.confirmpw) if qr[0] is True: self.passwd = iredutils.generate_password_hash(qr[1]) else: return qr if session.get('domainGlobalAdmin') is not True: # Verify old password. auth = core.Auth() qr = auth.auth(username=self.mail, password=self.cur_passwd, verifyPassword=True,) if qr[0] is False: return qr # Hash/Encrypt new password. try: self.conn.update( 'admin', vars=sql_vars, where='username=$username', password=self.passwd, passwordlastchange=iredutils.get_gmttime(), ) except Exception, e: raise web.seeother('/profile/admin/password/%s?msg=%s' % (self.mail, web.urlquote(e))) return (True,)
def update(self, profile_type, mail, data): self.profile_type = web.safestr(profile_type) self.mail = str(mail).lower() self.domain = self.mail.split("@", 1)[-1] # Pre-defined update key:value. updates = {"modified": iredutils.get_gmttime()} if self.profile_type == "general": # Get settings of domain admin and global admin managed_domain = "" if "domainadmin" in data: # isadmin=1 updates["isadmin"] = 1 managed_domain = self.domain else: updates["isadmin"] = 0 if session.get("domainGlobalAdmin"): if "domainGlobalAdmin" in data: updates["isadmin"] = 1 updates["isglobaladmin"] = 1 managed_domain = "ALL" else: updates["isglobaladmin"] = 0 # Delete records in domain_admins first self.conn.delete("domain_admins", vars={"username": self.mail}, where="username=$username") if updates.get("isadmin") == 1: try: self.conn.insert( "domain_admins", username=self.mail, domain=managed_domain, created=iredutils.get_gmttime(), active=1, ) except: pass # Get name cn = data.get("cn", "") updates["name"] = cn # Get preferred language: short lang code. e.g. en_US, de_DE. preferred_lang = web.safestr(data.get("preferredLanguage", "en_US")) # Must be equal to or less than 5 characters. if len(preferred_lang) > 5: preferred_lang = preferred_lang[:5] updates["language"] = preferred_lang # Update language immediately. if session.get("username") == self.mail and session.get("lang", "en_US") != preferred_lang: session["lang"] = preferred_lang # Get account status if "accountStatus" in data.keys(): updates["active"] = 1 else: updates["active"] = 0 # Get mail quota size. mailQuota = str(data.get("mailQuota")) if mailQuota.isdigit(): updates["quota"] = int(mailQuota) # Get employee id. employeeNumber = data.get("employeeNumber", "") updates["employeeid"] = employeeNumber elif self.profile_type == "password": newpw = str(data.get("newpw", "")) confirmpw = str(data.get("confirmpw", "")) # Verify new passwords. qr = iredutils.verify_new_password(newpw, confirmpw) if qr[0] is True: pwscheme = None if "storePasswordInPlainText" in data and settings.STORE_PASSWORD_IN_PLAIN_TEXT: pwscheme = "PLAIN" passwd = iredutils.generate_password_hash(qr[1], pwscheme=pwscheme) else: return qr # Hash/encrypt new password. updates["password"] = passwd # Update password last change date in column: passwordlastchange. # # Old iRedMail version doesn't have column mailbox.passwordlastchange, # so we update it with a seperate SQL command with exception handle. try: self.conn.update( "mailbox", vars={"username": self.mail}, where="username=$username", passwordlastchange=iredutils.get_gmttime(), ) except: pass else: return (True,) # Update SQL db try: self.conn.update( "mailbox", vars={"username": self.mail, "domain": self.domain}, where="username=$username AND domain=$domain", **updates ) # Update session immediately after updating SQL. if profile_type == "general": if not "domainGlobalAdmin" in data and session.get("username") == self.mail: session["domainGlobalAdmin"] = False return (True,) except Exception, e: return (False, str(e))
) # Update aliases, remove deleted users. for als in qr: exist_members = [v for v in str(als.goto).replace(' ', '').split(',')] # Skip if MySQL pattern matching doesn't get correct results. if not set(accounts) & set(exist_members): continue self.conn.update( 'alias', vars={'address': als.address, }, where='address = $address', goto=','.join([str(v) for v in exist_members if v not in accounts]), modified=iredutils.get_gmttime(), ) except Exception, e: pass except Exception, e: return (False, str(e)) elif accountType == 'admin': accounts = [str(v) for v in accounts if iredutils.is_email(v)] try: self.conn.delete( 'admin', vars={'accounts': accounts, }, where='username IN $accounts', ) except Exception, e:
def update(mail, profile_type, form, conn=None): mail = str(mail).lower() # Don't allow to view/update other admins' profile. if mail != session.get('username') and not session.get('is_global_admin'): return (False, 'PERMISSION_DENIED') sql_vars = {'username': mail} if not conn: _wrap = SQLWrap() conn = _wrap.conn m_doms = [] try: res = conn.select('domain_admins', vars={"uname": mail}, what="domain", where="username=$uname") for io in res: m_doms.append(io.domain) except: m_doms = [] fm_doms = [] try: fm_doms = form.managed_domains except: fm_doms = [] del_dom = [] add_dom = [] if len(m_doms) > 0 and len(fm_doms) > 0: for dm in m_doms: if dm not in fm_doms: del_dom.append(dm) for dm in fm_doms: if dm not in m_doms: add_dom.append(dm) params = {} if profile_type == 'general': # Name, preferred language params['name'] = form.get('cn', '') params['language'] = form_utils.get_language(form) # Update account status params['active'] = 0 if 'accountStatus' in form: params['active'] = 1 elif profile_type == 'password': newpw = web.safestr(form.get('newpw', '')) confirmpw = web.safestr(form.get('confirmpw', '')) # Verify new passwords. qr = iredpwd.verify_new_password(newpw=newpw, confirmpw=confirmpw) if qr[0] is True: passwd = iredpwd.generate_password_hash(qr[1]) params['password'] = passwd params['passwordlastchange'] = iredutils.get_gmttime() else: return qr if params: try: conn.update('admin', vars=sql_vars, where='username=$username', **params) except Exception as e: log_traceback() if 'password' in params: raise web.seeother('/profile/admin/password/{}?msg={}'.format( mail, web.urlquote(e))) else: raise web.seeother('/profile/admin/general/{}?msg={}'.format( mail, web.urlquote(e))) if len(add_dom) > 0: tm = False err = "" for i in add_dom: try: conn.insert('domain_admins', username=mail, domain=i, created=iredutils.get_gmttime(), active='1') except Exception as e: err += ", " + repr(e) tm = True if tm: raise web.seeother('/profile/admin/general/{}?msg={}'.format( mail, web.urlquote(err))) if len(del_dom) > 0: tm = False err = "" for i in del_dom: try: conn.delete('domain_admins', vars={ "umail": mail, "dm": i }, where="username=$umail and domain=$dm") except Exception as e: err += ", " + repr(e) tm = True if tm: raise web.seeother('/profile/admin/general/{}?msg={}'.format( mail, web.urlquote(err))) return (True, )
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') sql_vars = { 'username': self.mail, } if self.profile_type == 'general': # Get name self.cn = data.get('cn', '') # Get preferred language. self.preferredLanguage = str(data.get('preferredLanguage', 'en_US')) # Update in SQL db. try: self.conn.update( 'admin', vars=sql_vars, where='username=$username', name=self.cn, language=self.preferredLanguage, ) # Update language immediately. if session.get('username') == self.mail and \ session.get('lang', 'en_US') != self.preferredLanguage: session['lang'] = self.preferredLanguage except Exception as e: return (False, str(e)) if session.get('domainGlobalAdmin') is True: # Update account status self.accountStatus = '0' # Disabled if 'accountStatus' in list(data.keys()): self.accountStatus = '1' # Active try: self.conn.update( 'admin', vars=sql_vars, where='username=$username', active=self.accountStatus, ) except Exception as e: return (False, str(e)) elif self.profile_type == 'password': self.cur_passwd = str(data.get('oldpw', '')) self.newpw = web.safestr(data.get('newpw', '')) self.confirmpw = web.safestr(data.get('confirmpw', '')) # Verify new passwords. qr = iredutils.verify_new_password(self.newpw, self.confirmpw) if qr[0] is True: self.passwd = iredutils.generate_password_hash(qr[1]) else: return qr if session.get('domainGlobalAdmin') is not True: # Verify old password. auth = core.Auth() qr = auth.auth( username=self.mail, password=self.cur_passwd, verifyPassword=True, ) if qr[0] is False: return qr # Hash/Encrypt new password. try: self.conn.update( 'admin', vars=sql_vars, where='username=$username', password=self.passwd, passwordlastchange=iredutils.get_gmttime(), ) except Exception as e: raise web.seeother('/profile/admin/password/%s?msg=%s' % (self.mail, web.urlquote(e))) return (True, )
def update(domain, profile_type, form, conn=None): profile_type = str(profile_type) domain = str(domain).lower() sql_vars = {'domain': domain} if not conn: _wrap = SQLWrap() conn = _wrap.conn db_settings = iredutils.get_settings_from_db() # Get current domain profile qr = simple_profile(conn=conn, domain=domain) if qr[0]: domain_profile = qr[1] domain_settings = sqlutils.account_settings_string_to_dict( domain_profile.get('settings', '')) del qr else: return qr # Check disabled domain profiles disabled_domain_profiles = [] if not session.get('is_global_admin'): disabled_domain_profiles = domain_settings.get( 'disabled_domain_profiles', []) if profile_type in disabled_domain_profiles: return (False, 'PERMISSION_DENIED') # Pre-defined update key:value. updates = {'modified': iredutils.get_gmttime()} if profile_type == 'general': # Get name cn = form.get('cn', '') updates['description'] = cn # Get default quota for new user. default_user_quota = form_utils.get_single_value( form=form, input_name='defaultQuota', default_value=0, is_integer=True) if default_user_quota > 0: domain_settings['default_user_quota'] = default_user_quota else: if 'default_user_quota' in domain_settings: domain_settings.pop('default_user_quota') elif profile_type == 'advanced': # Update min/max password length in domain setting if session.get('is_global_admin') or ('password_policies' not in disabled_domain_profiles): for (_input_name, _key_name) in [('minPasswordLength', 'min_passwd_length'), ('maxPasswordLength', 'max_passwd_length')]: try: _length = int(form.get(_input_name, 0)) except: _length = 0 if _length > 0: if not session.get('is_global_admin'): # Make sure domain setting doesn't exceed global setting. if _input_name == 'minPasswordLength': # Cannot be shorter than global setting. if _length < db_settings['min_passwd_length']: _length = db_settings['min_passwd_length'] elif _input_name == 'maxPasswordLength': # Cannot be longer than global setting. if (db_settings['max_passwd_length'] > 0) and \ (_length > db_settings['max_passwd_length'] or _length <= db_settings['min_passwd_length']): _length = db_settings['max_passwd_length'] domain_settings[_key_name] = _length else: if _key_name in domain_settings: domain_settings.pop(_key_name) # Update default language for new user default_language = form_utils.get_language(form) if default_language in iredutils.get_language_maps(): domain_settings['default_language'] = default_language domain_settings['timezone'] = form_utils.get_timezone(form) updates['settings'] = sqlutils.account_settings_dict_to_string( domain_settings) try: conn.update('domain', vars=sql_vars, where='domain=$domain', **updates) log_activity(msg="Update domain profile: {} ({}).".format( domain, profile_type), domain=domain, event='update') return (True, ) except Exception as e: return (False, repr(e))
# Skip if MySQL pattern matching doesn't get correct results. if not set(accounts) & set(exist_members): continue self.conn.update( 'alias', vars={ 'address': als.address, }, where='address = $address', goto=','.join([ str(v) for v in exist_members if v not in accounts ]), modified=iredutils.get_gmttime(), ) except Exception, e: pass except Exception, e: return (False, str(e)) elif accountType == 'admin': accounts = [str(v) for v in accounts if iredutils.is_email(v)] try: self.conn.delete( 'admin', vars={ 'accounts': accounts, }, where='username IN $accounts',
def add_admin_from_form(form, conn=None): mail = web.safestr(form.get('mail')).strip().lower() if not iredutils.is_email(mail): return (False, 'INVALID_MAIL') # Get new password. newpw = web.safestr(form.get('newpw')) confirmpw = web.safestr(form.get('confirmpw')) qr = iredpwd.verify_new_password(newpw=newpw, confirmpw=confirmpw) if qr[0] is True: passwd = qr[1] else: return qr if not conn: _wrap = SQLWrap() conn = _wrap.conn # Check local domain domain = mail.split('@', 1)[-1] if not iredutils.is_domain(domain): return (False, 'INVALID_DOMAIN') if sql_lib_general.is_domain_exists(domain=domain, conn=conn): return (False, 'CAN_NOT_BE_LOCAL_DOMAIN') # Check admin exist. if is_admin_exists(conn=conn, admin=mail): return (False, 'ALREADY_EXISTS') # Name, language cn = form.get('cn', '') managed_domains = form.get('managed_domains', []) lang = form_utils.get_language(form) _status = form_utils.get_single_value(form=form, input_name='accountStatus', default_value='active') if _status == 'active': _status = 1 else: _status = 0 # GET ALL valid DOMAINS all_domains = sql_lib_domain.get_all_domains(conn=conn, name_only=True) if all_domains[0]: all_domains = all_domains[1] else: all_domains = [] #Check form submitted DOMAINS for validity for i in managed_domains: if i not in all_domains: if i != "ALL": managed_domains = list(filter((i).__ne__, managed_domains)) managed_domains = list(set(managed_domains)) try: if len(managed_domains) > 0: conn.insert('admin', username=mail, name=cn, password=iredpwd.generate_password_hash(passwd), language=lang, created=iredutils.get_gmttime(), active=_status) for i in managed_domains: conn.insert('domain_admins', username=mail, domain=i, created=iredutils.get_gmttime(), active='1') log_activity(msg="Create admin: %s." % (mail), event='create') return (True, ) else: return (False, "No Valid Domain Selected!") except Exception as e: log_traceback() return (False, repr(e))