def get_domain_settings(domain, domain_profile=None, conn=None): domain = str(domain).lower() try: if not domain_profile: if not conn: _wrap = SQLWrap() conn = _wrap.conn qr = conn.select('domain', vars={'domain': domain}, what='settings', where='domain=$domain', limit=1) if qr: domain_profile = list(qr)[0] else: return (False, 'INVALID_DOMAIN_NAME') ps = domain_profile.get('settings', '') ds = sqlutils.account_settings_string_to_dict(ps) return (True, ds) except Exception as e: return (False, repr(e))
def GET(self, domain): domain = str(domain).lower() form = web.input() # Get all managed domains. _wrap = SQLWrap() conn = _wrap.conn if session.get('is_global_admin'): qr = sql_lib_domain.get_all_domains(conn=conn, name_only=True) else: qr = sql_lib_admin.get_managed_domains( conn=conn, admin=session.get('username'), domain_name_only=True) if qr[0] is True: all_domains = qr[1] else: raise web.seeother('/api?msg=' + web.urlquote(qr[1])) # Get domain profile. qr_profile = sql_lib_domain.simple_profile(domain=domain, conn=conn) if qr_profile[0] is True: domain_profile = qr_profile[1] domain_settings = sqlutils.account_settings_string_to_dict( domain_profile['settings']) else: raise web.seeother('/api?msg=%s' % web.urlquote(qr_profile[1])) # Cet total number and allocated quota size of existing users under domain. num_users_under_domain = sql_lib_general.num_users_under_domain( domain=domain, conn=conn) min_passwd_length = domain_settings.get('min_passwd_length', settings.min_passwd_length) max_passwd_length = domain_settings.get('max_passwd_length', settings.max_passwd_length) return web.render( 'api/msg/msg.html', content_type="application/json", msg={ #"cur_domain":domain, #"allDomains":all_domains, #"profile":domain_profile, #"domain_settings":domain_settings, #"min_passwd_length":min_passwd_length, #"max_passwd_length":max_passwd_length, #"store_password_in_plain_text":settings.STORE_PASSWORD_IN_PLAIN_TEXT, #"num_existing_users":num_users_under_domain, #"languagemaps":iredutils.get_language_maps(), #"password_policies":iredutils.get_password_policies(), #"msg":form.get('msg') "msg": "Create User API's GET method!" })
def GET(self, domain): domain = str(domain).lower() form = web.input() # Get all managed domains. _wrap = SQLWrap() conn = _wrap.conn if session.get('is_global_admin'): qr = sql_lib_domain.get_all_domains(conn=conn, name_only=True) else: qr = sql_lib_admin.get_managed_domains( conn=conn, admin=session.get('username'), domain_name_only=True) if qr[0] is True: all_domains = qr[1] else: raise web.seeother('/domains?msg=' + web.urlquote(qr[1])) # Get domain profile. qr_profile = sql_lib_domain.simple_profile(domain=domain, conn=conn) if qr_profile[0] is True: domain_profile = qr_profile[1] domain_settings = sqlutils.account_settings_string_to_dict( domain_profile['settings']) else: raise web.seeother('/domains?msg=%s' % web.urlquote(qr_profile[1])) # Cet total number and allocated quota size of existing users under domain. num_users_under_domain = sql_lib_general.num_users_under_domain( domain=domain, conn=conn) min_passwd_length = domain_settings.get('min_passwd_length', settings.min_passwd_length) max_passwd_length = domain_settings.get('max_passwd_length', settings.max_passwd_length) return web.render( 'sql/user/create.html', cur_domain=domain, allDomains=all_domains, profile=domain_profile, domain_settings=domain_settings, min_passwd_length=min_passwd_length, max_passwd_length=max_passwd_length, store_password_in_plain_text=settings.STORE_PASSWORD_IN_PLAIN_TEXT, num_existing_users=num_users_under_domain, languagemaps=iredutils.get_language_maps(), password_policies=iredutils.get_password_policies(), msg=form.get('msg'), )
def get_admin_settings(admin=None, existing_settings=None, conn=None) -> Tuple: """Return a dict of per-admin settings. :param admin: mail address of domain admin :param existing_settings: original value of sql column `settings` :param conn: SQL connection cursor """ if not admin: admin = session.get('username') if not iredutils.is_email(admin): return (False, 'INVALID_ADMIN') if not conn: _wrap = SQLWrap() conn = _wrap.conn account_settings = {} # Get settings stored in sql column `mailbox.settings` if existing_settings: orig_settings = existing_settings else: try: qr = conn.select( 'mailbox', vars={'username': admin}, what='settings', where='username=$username AND (isadmin=1 OR isglobaladmin=1)', limit=1) if not qr: # Not a mail user qr = conn.select('admin', vars={'username': admin}, what='settings', where='username=$username', limit=1) if not qr: return (False, 'INVALID_ADMIN') orig_settings = qr[0]['settings'] except Exception as e: return (False, repr(e)) if orig_settings: account_settings = sqlutils.account_settings_string_to_dict( orig_settings) return (True, account_settings)
def GET(self, profile_type, domain): form = web.input() domain = web.safestr(domain.split('/', 1)[0]) profile_type = web.safestr(profile_type) #check if admin asking for details of correct domain admins_of_domain = sql_lib_domain.get_domain_admin_addresses( domain=domain)[1] if session.get('username') not in admins_of_domain and not session.get( 'is_global_admin'): raise web.seeother( '/domains?msg=PERMISSION_DENIED_TRYING_TO_ACCESS_OUT_OF_BOUND_DOMAIN' ) _wrap = SQLWrap() conn = _wrap.conn result = sql_lib_domain.profile(conn=conn, domain=domain) if result[0] is not True: raise web.seeother('/domains?msg=' + web.urlquote(result[1])) domain_profile = result[1] # Get settings from db. _settings = iredutils.get_settings_from_db( params=['min_passwd_length', 'max_passwd_length']) global_min_passwd_length = _settings['min_passwd_length'] global_max_passwd_length = _settings['max_passwd_length'] return web.render( 'sql/domain/profile.html', cur_domain=domain, profile_type=profile_type, profile=domain_profile, default_mta_transport=settings.default_mta_transport, domain_settings=sqlutils.account_settings_string_to_dict( domain_profile['settings']), global_min_passwd_length=global_min_passwd_length, global_max_passwd_length=global_max_passwd_length, timezones=TIMEZONES, # Language languagemaps=iredutils.get_language_maps(), msg=form.get('msg'), )
def get_user_settings(mail, existing_settings=None, conn=None): """Return dict of per-user settings stored in SQL column: mailbox.settings. :param mail: full user email address. :param existing_settings: original value of sql column `mailbox.settings`. :param conn: sql connection cursor. """ if not iredutils.is_email(mail): return (False, 'INVALID_MAIL') if not conn: _wrap = SQLWrap() conn = _wrap.conn user_settings = {} # Get settings stored in sql column `mailbox.settings` if existing_settings: orig_settings = existing_settings else: try: qr = conn.select('mailbox', vars={'username': mail}, what='settings', where='username=$username', limit=1) if qr: orig_settings = qr[0]['settings'] else: return (False, 'NO_SUCH_ACCOUNT') except Exception as e: return (False, repr(e)) if orig_settings: user_settings = sqlutils.account_settings_string_to_dict(orig_settings) return (True, user_settings)
def GET(self, profile_type, domain): form = web.input() domain = web.safestr(domain.split('/', 1)[0]) profile_type = web.safestr(profile_type) _wrap = SQLWrap() conn = _wrap.conn result = sql_lib_domain.profile(conn=conn, domain=domain) if result[0] is not True: raise web.seeother('/domains?msg=' + web.urlquote(result[1])) domain_profile = result[1] # Get settings from db. _settings = iredutils.get_settings_from_db( params=['min_passwd_length', 'max_passwd_length']) global_min_passwd_length = _settings['min_passwd_length'] global_max_passwd_length = _settings['max_passwd_length'] return web.render( 'sql/domain/profile.html', cur_domain=domain, profile_type=profile_type, profile=domain_profile, default_mta_transport=settings.default_mta_transport, domain_settings=sqlutils.account_settings_string_to_dict( domain_profile['settings']), global_min_passwd_length=global_min_passwd_length, global_max_passwd_length=global_max_passwd_length, timezones=TIMEZONES, # Language languagemaps=iredutils.get_language_maps(), msg=form.get('msg'), )
def auth(conn, username=False, password=False, is_api_login=False, api_key=False, account_type='admin', verify_password=False): result = False kresult = {} # validate username, password and extract domain from username, if not API login if is_api_login == False: if not iredutils.is_email(username): return (False, 'INVALID_USERNAME') if not password: return (False, 'EMPTY_PASSWORD') username = str(username).lower() password = str(password) domain = username.split('@', 1)[-1] #if API login, get api_key string and check_api_key_sanitization else: if len(str(api_key).strip()) != 256: api_key = "" session.kill() return (False, 'INVALID_API_KEY') else: api_key = check_api_key_sanitization(str(api_key)) if api_key == "": session.kill() return (False, 'INVALID_API_KEY') # Query database for accounts # if not API login and account_type is set to 'admin' if account_type == 'admin' and not is_api_login: # query admin table for account result = conn.select('admin', vars={'username': username}, where="username=$username AND active=1", what='password, language, settings', limit=1) # if account not found in admin table, query mailbox table ,in case mail user is marked as domain admin if not result: result = conn.select( 'mailbox', vars={'username': username}, where= "username=$username AND active=1 AND (isadmin=1 OR isglobaladmin=1)", what='password, language, isadmin, isglobaladmin, settings', limit=1, ) #if account found set admin_is_mail_user session if result: session['admin_is_mail_user'] = True # if not API login and account_type is set to 'user' elif account_type == 'user' and not is_api_login: # query mailbox table for account result = conn.select( 'mailbox', vars={'username': username}, what='password, language, isadmin, isglobaladmin, settings', where="username=$username AND active=1", limit=1) # if API login and account_type is set to 'admin' elif account_type == 'admin' and is_api_login: # query api table for given api_key key_sql = "SELECT * FROM api where api_key='" + api_key + "' AND is_enabled=1 AND isglobaladminapi=1" result = conn.query(key_sql) # if api_key not fount, then kill session and push INVALID_API_KEY message if len(result) == 0: session.kill() return (False, 'INVALID_API_KEY') # get current time now = datetime.datetime.now() kresult = dict(result[0]) # if api_key has expired, then kill session and set the key in database to be disabled and push INVALID_API_KEY message if kresult.get('expiry_date_time') < now: conn.update('api', where="kid=" + str(kresult.get('kid')).strip(), is_enabled="0") session.kill() return (False, 'INVALID_API_KEY') # if api_key is disabled, then kill session and push INVALID_API_KEY message if str(kresult.get('is_enabled')).strip() == "0": session.kill() return (False, 'INVALID_API_KEY') # if account_type is invalid or Key is invalid else: # if not API login push INVALID_ACCOUNT_TYPE messgae, else push INVALID_API_KEY message if not is_api_login: return (False, 'INVALID_ACCOUNT_TYPE') else: return (False, 'INVALID_API_KEY') # Account not found, push INVALID_CREDENTIALS message if not result: # Do NOT return msg like 'Account does not ***EXIST***', crackers can use it to verify valid accounts. return (False, 'INVALID_CREDENTIALS') account_settings = "" record = "" # get user account settings if not API login if not is_api_login: record = result[0] account_settings = sqlutils.account_settings_string_to_dict( str(record.settings)) # get API account settings if API login else: record = kresult account_settings = sqlutils.account_settings_string_to_dict( str(record.get('settings'))) # Verify password, if not API login if not is_api_login: password_sql = str(record.password) if not iredpwd.verify_password_hash(password_sql, password): return (False, 'INVALID_CREDENTIALS') # set is_global_admin, is_global_admin_api, global_admin_api_key in session, if KEY is of type 'isglobaladminapi' if record.get('isglobaladminapi', 0) == 1: session['is_global_admin'] = True session['is_global_admin_api'] = True session['global_admin_api_key'] = api_key # if Not API login set username, lang, timezone, is_global_admin, is_admin in session for users if (not verify_password) and (not is_api_login): session['username'] = username # Set preferred language. session['lang'] = web.safestr( record.get('language', settings.default_language)) # Set timezone (GMT-XX:XX). # Priority: per-user timezone > per-domain > global setting timezone = settings.LOCAL_TIMEZONE if 'timezone' in account_settings: tz_name = account_settings['timezone'] if tz_name in TIMEZONES: timezone = TIMEZONES[tz_name] else: # Get per-domain timezone qr_domain = conn.select('domain', vars={'domain': domain}, what='settings', where='domain=$domain', limit=1) if qr_domain: domain_settings = sqlutils.account_settings_string_to_dict( str(qr_domain[0]['settings'])) if 'timezone' in domain_settings: tz_name = domain_settings['timezone'] if tz_name in TIMEZONES: timezone = TIMEZONES[tz_name] session['timezone'] = timezone # Set session['is_global_admin'] if admin is a mail user if session.get('admin_is_mail_user'): if record.get('isglobaladmin', 0) == 1: session['is_global_admin'] = True if record.get('isadmin', 0) == 1: session['is_admin'] = True # set session for 'is_global_admin', 'is_admin' if admin is domain_admin else: # find global admin with domain admin with domains ALL try: result = conn.select( 'domain_admins', vars={ 'username': username, 'domain': 'ALL' }, what='domain', where='username=$username AND domain=$domain', limit=1) if result: session['is_global_admin'] = True session['is_admin'] = True except: pass # if not global admin but domain admin and not a mail user try: result = conn.select( 'domain_admins', vars={'username': username}, what='domain', where='username=$username', ) if result: session['is_admin'] = True except: pass #set logged, cookie_name, cookie_name, ignore_expiry in session session['logged'] = True web.config.session_parameters['cookie_name'] = 'iRedAdmin' web.config.session_parameters[ 'ignore_change_ip'] = settings.SESSION_IGNORE_CHANGE_IP web.config.session_parameters['ignore_expiry'] = False # return authentication return (True, {'account_settings': account_settings})
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))
def GET(self, mail): mail = str(mail).lower() domain = mail.split('@', 1)[-1] _wrap = SQLWrap() conn = _wrap.conn form = web.input() msg = form.get('msg', '') used_quota = {} qr = sql_lib_user.profile(mail=mail, conn=conn) if qr[0]: user_profile = qr[1] else: raise web.seeother('/api?msg={}'.format(web.urlquote(qr[1]))) del qr # Get per-user settings user_settings = {} qr = sql_lib_general.get_user_settings( conn=conn, mail=mail, existing_settings=user_profile['settings']) if qr[0]: user_settings = qr[1] del qr # Get used quota. if settings.SHOW_USED_QUOTA: used_quota = sql_lib_general.get_account_used_quota( accounts=[mail], conn=conn) # Get per-domain disabled user profiles. qr = sql_lib_domain.simple_profile(conn=conn, domain=domain, columns=['settings']) if qr[0]: domain_profile = qr[1] domain_settings = sqlutils.account_settings_string_to_dict( domain_profile['settings']) min_passwd_length = domain_settings.get('min_passwd_length', settings.min_passwd_length) max_passwd_length = domain_settings.get('max_passwd_length', settings.max_passwd_length) return web.render('api/msg/msg.html', content_type="application/json", msg={ "cur_domain": domain, "mail": mail, "profile": user_profile, "timezones": TIMEZONES, "min_passwd_length": min_passwd_length, "max_passwd_length": max_passwd_length, "store_password_in_plain_text": settings.STORE_PASSWORD_IN_PLAIN_TEXT, "password_policies": iredutils.get_password_policies(), "user_settings": user_settings, "used_quota": used_quota, "languagemaps": iredutils.get_language_maps(), "msg": msg, })
def auth(conn, username, password, account_type='admin', verify_password=False): if not iredutils.is_email(username): return (False, 'INVALID_USERNAME') if not password: return (False, 'EMPTY_PASSWORD') username = str(username).lower() password = str(password) domain = username.split('@', 1)[-1] # Query account from SQL database. if account_type == 'admin': # separate admin accounts result = conn.select('admin', vars={'username': username}, where="username=$username AND active=1", what='password, language, settings', limit=1) # mail user marked as domain admin if not result: result = conn.select( 'mailbox', vars={'username': username}, where= "username=$username AND active=1 AND (isadmin=1 OR isglobaladmin=1)", what='password, language, isadmin, isglobaladmin, settings', limit=1, ) if result: session['admin_is_mail_user'] = True elif account_type == 'user': result = conn.select( 'mailbox', vars={'username': username}, what='password, language, isadmin, isglobaladmin, settings', where="username=$username AND active=1", limit=1) else: return (False, 'INVALID_ACCOUNT_TYPE') if not result: # Account not found. # Do NOT return msg like 'Account does not ***EXIST***', crackers # can use it to verify valid accounts. return (False, 'INVALID_CREDENTIALS') record = result[0] password_sql = str(record.password) account_settings = sqlutils.account_settings_string_to_dict( str(record.settings)) # Verify password if not iredpwd.verify_password_hash(password_sql, password): return (False, 'INVALID_CREDENTIALS') if not verify_password: session['username'] = username # Set preferred language. session['lang'] = web.safestr( record.get('language', settings.default_language)) # Set timezone (GMT-XX:XX). # Priority: per-user timezone > per-domain > global setting timezone = settings.LOCAL_TIMEZONE if 'timezone' in account_settings: tz_name = account_settings['timezone'] if tz_name in TIMEZONES: timezone = TIMEZONES[tz_name] else: # Get per-domain timezone qr_domain = conn.select('domain', vars={'domain': domain}, what='settings', where='domain=$domain', limit=1) if qr_domain: domain_settings = sqlutils.account_settings_string_to_dict( str(qr_domain[0]['settings'])) if 'timezone' in domain_settings: tz_name = domain_settings['timezone'] if tz_name in TIMEZONES: timezone = TIMEZONES[tz_name] session['timezone'] = timezone # Set session['is_global_admin'] if session.get('admin_is_mail_user'): if record.get('isglobaladmin', 0) == 1: session['is_global_admin'] = True else: try: result = conn.select( 'domain_admins', vars={ 'username': username, 'domain': 'ALL' }, what='domain', where='username=$username AND domain=$domain', limit=1) if result: session['is_global_admin'] = True except: pass session['logged'] = True web.config.session_parameters['cookie_name'] = 'iRedAdmin' web.config.session_parameters[ 'ignore_change_ip'] = settings.SESSION_IGNORE_CHANGE_IP web.config.session_parameters['ignore_expiry'] = False return (True, {'account_settings': account_settings})
def GET(self, profile_type, mail): mail = str(mail).lower() domain = mail.split('@', 1)[-1] _wrap = SQLWrap() conn = _wrap.conn form = web.input() msg = form.get('msg', '') # profile_type == 'general' used_quota = {} qr = sql_lib_user.profile(mail=mail, conn=conn) if qr[0]: user_profile = qr[1] else: raise web.seeother('/users/{}?msg={}'.format( domain, web.urlquote(qr[1]))) del qr # Get per-user settings user_settings = {} qr = sql_lib_general.get_user_settings( conn=conn, mail=mail, existing_settings=user_profile['settings']) if qr[0]: user_settings = qr[1] del qr # Get used quota. if settings.SHOW_USED_QUOTA: used_quota = sql_lib_general.get_account_used_quota( accounts=[mail], conn=conn) # Get per-domain disabled user profiles. qr = sql_lib_domain.simple_profile(conn=conn, domain=domain, columns=['settings']) if qr[0]: domain_profile = qr[1] domain_settings = sqlutils.account_settings_string_to_dict( domain_profile['settings']) min_passwd_length = domain_settings.get('min_passwd_length', settings.min_passwd_length) max_passwd_length = domain_settings.get('max_passwd_length', settings.max_passwd_length) return web.render( 'sql/user/profile.html', cur_domain=domain, mail=mail, profile_type=profile_type, profile=user_profile, timezones=TIMEZONES, min_passwd_length=min_passwd_length, max_passwd_length=max_passwd_length, store_password_in_plain_text=settings.STORE_PASSWORD_IN_PLAIN_TEXT, password_policies=iredutils.get_password_policies(), user_settings=user_settings, used_quota=used_quota, languagemaps=iredutils.get_language_maps(), msg=msg, )
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_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))