Пример #1
0
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))
Пример #2
0
    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!"
            })
Пример #3
0
    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'),
        )
Пример #4
0
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)
Пример #5
0
    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'),
        )
Пример #6
0
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)
Пример #7
0
    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'),
        )
Пример #8
0
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})
Пример #9
0
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))
Пример #10
0
    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,
                          })
Пример #11
0
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})
Пример #12
0
    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,
        )
Пример #13
0
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))
Пример #14
0
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))