示例#1
0
def delete_admins(mails, revoke_admin_privilege_from_user=True, conn=None):
    mails = [str(v) for v in mails if iredutils.is_email(v)]

    if not mails:
        return (True, )

    sql_vars = {'mails': mails}

    try:
        if not conn:
            _wrap = SQLWrap()
            conn = _wrap.conn

        # Standalone mail admins
        conn.delete('admin', vars=sql_vars, where='username IN $mails')

        conn.delete('domain_admins', vars=sql_vars, where='username IN $mails')

        # Unmark globa/domain admin which is mail user
        if revoke_admin_privilege_from_user:
            conn.update(
                'mailbox',
                vars=sql_vars,
                where='username IN $mails AND (isadmin=1 OR isglobaladmin=1)',
                isadmin=0,
                isglobaladmin=0)

        log_activity(event='delete',
                     msg="Delete admin(s): %s." % ', '.join(mails))

        return (True, )
    except Exception as e:
        log_traceback()
        return (False, repr(e))
示例#2
0
def get_nic_info():
    # Return list of basic info of available network interfaces.
    # Format: [(name, ip_address, netmask), ...]
    # Sample: [('eth0', '192.168.1.1', '255.255.255.0'), ...]
    netif_data = []

    try:
        import netifaces
    except:
        return netif_data

    try:
        ifaces = netifaces.interfaces()

        for iface in ifaces:
            if iface in ["lo", "lo0"]:
                # `lo` -> Linux
                # `lo0` -> OpenBSD
                continue

            try:
                addr = netifaces.ifaddresses(iface)

                for af in addr:
                    if af in (netifaces.AF_INET, netifaces.AF_INET6):
                        for item in addr[af]:
                            netif_data.append(
                                (iface, item.get("addr",
                                                 ""), item.get("netmask", "")))
            except:
                log_traceback()
    except:
        log_traceback()

    return netif_data
示例#3
0
def get_profile(mail, columns=None, conn=None):
    if not iredutils.is_email(mail):
        return (False, 'INVALID_MAIL')

    if isinstance(columns, (list, tuple, set)):
        columns = ','.join(columns)
    else:
        columns = '*'

    if not conn:
        _wrap = SQLWrap()
        conn = _wrap.conn

    try:
        qr = conn.select('admin',
                         vars={'username': mail},
                         what=columns,
                         where='username=$username',
                         limit=1)

        if qr:
            return (True, list(qr)[0])
        else:
            return (False, 'NO_SUCH_ACCOUNT')
    except Exception as e:
        log_traceback()
        return (False, repr(e))
示例#4
0
def revoke_admin_privilege_if_no_managed_domains(admin=None, conn=None):
    """If given admin doesn't manage any domain, revoke the admin privilege.

    @admin -- email address of domain admin
    @conn -- sql connection cursor
    """
    if not admin:
        return (True, )

    if not conn:
        _wrap = SQLWrap()
        conn = _wrap.conn

    # Return immediately if it's a global admin
    if sql_lib_general.is_global_admin(admin=admin, conn=conn):
        return (True, )

    if not num_managed_domains(admin=admin, conn=conn):
        try:
            conn.update('mailbox',
                        vars={'admin': admin},
                        isadmin=0,
                        where='username=$admin')
        except Exception as e:
            log_traceback()
            return (False, repr(e))

    return (True, )
示例#5
0
def filter_existing_emails(mails, base_dn=None, conn=None):
    """
    Remove non-existing addresses from given list of mail addresses, return a
    list of existing ones.

    :param mails: list of email addresses
    :param base_dn: if not present, search from `settings.ldap_basedn`
    :param conn: ldap connection cursor
    """
    mails = [str(v).lower()
             for v in mails
             if iredutils.is_email(v)]
    mails = list(set(mails))

    result = {'exist': [], 'nonexist': []}

    if not mails:
        return result

    if not conn:
        _wrap = LDAPWrap()
        conn = _wrap.conn

    _filter = '(&'
    _filter += '(|(objectClass=mailUser)(objectClass=mailList)(objectClass=mailAlias))'
    _filter += '(|'
    for addr in mails:
        _filter += '(mail={})(shadowAddress={})'.format(addr, addr)

    _filter += '))'

    if not base_dn:
        base_dn = settings.ldap_basedn

    try:
        qr = conn.search_s(base_dn,
                           ldap.SCOPE_SUBTREE,
                           _filter,
                           ['mail', 'shadowAddress'])

        if not qr:
            # None of them exists.
            result['nonexist'] = mails
        else:
            for (_dn, _ldif) in qr:
                _ldif = iredutils.bytes2str(_ldif)
                result['exist'] += _ldif.get('mail', []) + _ldif.get('shadowAddress', [])

            result['nonexist'] = [v for v in mails if v not in result['exist']]

        # Remove duplicates and sort.
        result['exist'] = list(set(result['exist']))
        result['nonexist'] = list(set(result['nonexist']))
    except:
        log_traceback()

    return result
示例#6
0
def parse_raw_message(msg: bytes):
    """Read RAW message from string. Return tuple of:

    list of multiple mail headers: [[header: value], [header: value], ...]
    list of (multiple) body parts: [part1, part2, ...]
    list of attachment file names: [name1, name2, ...]
    """

    # Get all mail headers. Sample:
    # [{'From': '*****@*****.**'}, {'To': '*****@*****.**'}]
    headers = []

    # Get decoded content parts of mail body.
    bodies = []

    # Get list of attachment names.
    attachments = []

    msg = email.message_from_bytes(msg)

    # Extract all headers.
    for i in __decode_headers(msg):
        for k in i:
            headers += [(k, i[k])]

    for part in msg.walk():
        _content_type = part.get_content_maintype()

        # multipart/* is just a container
        if _content_type == 'multipart':
            continue

        # either a string or None.
        _filename = part.get_filename()
        if _filename:
            attachments += [_filename]

        if _content_type == 'text':
            # Plain text, not an attachment.
            try:
                if part.get_content_charset():
                    encoding = part.get_content_charset()
                elif part.get_charset():
                    encoding = part.get_charset()
                else:
                    encoding = 'utf-8'

                text = str(part.get_payload(decode=True),
                           encoding=encoding,
                           errors='replace')

                text = text.strip()
                bodies.append(text)
            except:
                log_traceback()

    return (headers, bodies, attachments)
示例#7
0
def __update_num_domain_current_accounts(domain,
                                         increase=False,
                                         decrease=False,
                                         step_number=1,
                                         account_type='user',
                                         conn=None):
    """Increase or decrease number of existing accounts in domain profile."""
    if not isinstance(step_number, int):
        step_number = 1

    if step_number <= 0:
        step_number = 1

    attr_map = {
        'user': '******',
        'alias': 'domainCurrentAliasNumber',
        'maillist': 'domainCurrentListNumber',
    }
    attr_count = attr_map[account_type]

    if not conn:
        _wrap = LDAPWrap()
        conn = _wrap.conn

    dn = ldaputils.rdn_value_to_domain_dn(domain)

    # Get domain profile first
    try:
        qr = conn.search_s(dn,
                           ldap.SCOPE_BASE,
                           '(&(objectClass=mailDomain)(domainName=%s))' % domain,
                           [attr_count])

    except Exception as e:
        log_traceback()
        return (False, repr(e))

    if qr:
        _ldif = iredutils.bytes2str(qr[0][1])
        _current = int(_ldif.get(attr_count, [0])[0])

        _num = _current
        if increase:
            _num = _current + step_number
        elif decrease:
            _num = _current - step_number

        if _num < 0:
            _num = 0

        # Update count
        update_attr_with_single_value(dn=dn,
                                      attr=attr_count,
                                      value=_num,
                                      conn=conn)

    return (True, )
示例#8
0
def num_managed_users(admin=None, domains=None, conn=None, listed_only=False):
    """Count users of all managed domains."""
    num = 0

    if not admin:
        admin = session.get('username')

    if not conn:
        _wrap = SQLWrap()
        conn = _wrap.conn

    if domains:
        domains = [str(d).lower() for d in domains if iredutils.is_domain(d)]
    else:
        qr = get_managed_domains(conn=conn,
                                 admin=admin,
                                 domain_name_only=True,
                                 listed_only=listed_only)
        if qr[0]:
            domains = qr[1]

    if not domains:
        return num

    sql_vars = {'admin': admin, 'domains': domains}

    try:
        if sql_lib_general.is_global_admin(admin=admin, conn=conn):
            if domains:
                qr = conn.select('mailbox',
                                 vars=sql_vars,
                                 what='COUNT(username) AS total',
                                 where='domain IN $domains')
            else:
                qr = conn.select('mailbox', what='COUNT(username) AS total')
        else:
            sql_append_where = ''
            if domains:
                sql_append_where = 'AND mailbox.domain IN %s' % web.sqlquote(
                    domains)

            qr = conn.query(
                """
                SELECT COUNT(mailbox.username) AS total
                FROM mailbox
                LEFT JOIN domain_admins ON (mailbox.domain = domain_admins.domain)
                WHERE domain_admins.username=$admin %s
                """ % (sql_append_where),
                vars=sql_vars,
            )

        num = qr[0].total or 0
    except:
        log_traceback()

    return num
示例#9
0
def get_system_load_average():
    try:
        (a1, a2, a3) = getloadavg()
        a1 = "%.3f" % a1
        a2 = "%.3f" % a2
        a3 = "%.3f" % a3
        return (a1, a2, a3)
    except:
        log_traceback()
        return (0, 0, 0)
示例#10
0
def __num_accounts_under_domain(domain,
                                account_type='user',
                                disabled_only=False,
                                first_char=None,
                                update_statistics=False,
                                conn=None):
    """Get number of accounts under specified domain.

    :param domain: domain name you want to query.
    :param account_type: one of 'user', 'list', 'alias', 'ml', 'mixed_ml'.
    :param conn: ldap connection cursor.
    """
    domain = str(domain).lower()
    if not iredutils.is_domain(domain):
        return (False, 'INVALID_DOMAIN_NAME')

    dn_domain = ldaputils.rdn_value_to_domain_dn(domain)

    statistics_attr = None
    if account_type == 'user':
        search_filter = '(&(objectClass=mailUser)(!(mail=@%s)))' % domain
        statistics_attr = 'domainCurrentUserNumber'
    else:
        search_filter = '(&(objectClass=mailUser)(!(mail=@%s)))' % domain

    if disabled_only:
        search_filter = '(&' + search_filter + '(accountStatus=disabled)' + ')'

    if first_char:
        search_filter = '(&' + search_filter + '(|(cn=%s*)(mail=%s*))' + ')'

    if not conn:
        _wrap = LDAPWrap()
        conn = _wrap.conn

    try:
        qr = conn.search_s(dn_domain,
                           ldap.SCOPE_SUBTREE,
                           search_filter,
                           ['dn'])

        num = len(qr)

        if update_statistics and statistics_attr:
            mod_attr = ldaputils.mod_replace(statistics_attr, num)
            try:
                conn.modify_s(dn_domain, mod_attr)
            except:
                log_traceback()

        return num
    except:
        log_traceback()
        return 0
示例#11
0
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, )
示例#12
0
def get_managed_domains(admin,
                        domain_name_only=False,
                        listed_only=False,
                        conn=None):
    admin = str(admin).lower()

    if not iredutils.is_email(admin):
        return (False, 'INCORRECT_USERNAME')

    if not conn:
        _wrap = SQLWrap()
        conn = _wrap.conn

    try:
        if sql_lib_general.is_global_admin(admin=admin, conn=conn):
            if listed_only:
                result = conn.query("""
                    SELECT domain.domain
                      FROM domain
                 LEFT JOIN domain_admins ON (domain.domain=domain_admins.domain)
                     WHERE domain_admins.username=$admin
                     ORDER BY domain_admins.domain
                    """,
                                    vars={'admin': admin})
            else:
                result = conn.select('domain', what='domain', order='domain')
        else:
            sql_left_join = ''
            if not listed_only:
                sql_left_join = """OR domain_admins.domain='ALL'"""

            result = conn.query("""
                SELECT domain.domain
                  FROM domain
             LEFT JOIN domain_admins ON (domain.domain=domain_admins.domain %s)
                 WHERE domain_admins.username=$admin
              ORDER BY domain_admins.domain
                """ % (sql_left_join),
                                vars={'admin': admin})

        if domain_name_only:
            domains = []
            for i in result:
                _domain = str(i['domain']).lower()
                if iredutils.is_domain(_domain):
                    domains.append(_domain)

            return (True, domains)
        else:
            return (True, list(result))
    except Exception as e:
        log_traceback()
        return (False, repr(e))
示例#13
0
def num_managed_domains(admin=None,
                        disabled_only=False,
                        first_char=None,
                        conn=None):
    num = 0

    if not admin:
        admin = session.get('username')

    if not conn:
        _wrap = SQLWrap()
        conn = _wrap.conn

    sql_where = ''
    if disabled_only is True:
        sql_where += 'domain.active=0'

    if first_char:
        first_char = first_char[0].lower()

        if sql_where:
            sql_where += ' AND domain.domain LIKE %s' % web.sqlquote(
                first_char + '%')
        else:
            sql_where += 'domain.domain LIKE %s' % web.sqlquote(first_char +
                                                                '%')

    try:
        if sql_lib_general.is_global_admin(admin=admin, conn=conn):
            qr = conn.select('domain',
                             what='COUNT(domain) AS total',
                             where=sql_where or None)
        else:
            if sql_where:
                sql_where = 'AND ' + sql_where

            qr = conn.query("""
                SELECT COUNT(domain.domain) AS total
                FROM domain
                LEFT JOIN domain_admins ON (domain.domain=domain_admins.domain)
                WHERE domain_admins.username=$admin %s
                """ % (sql_where),
                            vars={'admin': admin})

        num = qr[0].total or 0
    except:
        log_traceback()

    return num
示例#14
0
def get_first_char_of_all_accounts(domain, account_type, conn=None):
    """Get first character of accounts under given domain.

    @domain - must be a valid domain name.
    @account_type - could be one of: user, ml, alias.
    @conn - SQL connection cursor
    """
    if not conn:
        _wrap = SQLWrap()
        conn = _wrap.conn

    type_map = {
        'user': {
            'table': 'mailbox',
            'column': 'username'
        },
        'alias': {
            'table': 'alias',
            'column': 'address'
        },
        'ml': {
            'table': 'maillists',
            'column': 'address'
        }
    }

    _table = type_map[account_type]['table']
    _column = type_map[account_type]['column']

    chars = []
    try:
        qr = conn.select(
            _table,
            vars={
                'domain': domain,
                'column': _column
            },
            what="SUBSTRING({} FROM 1 FOR 1) AS first_char".format(_column),
            where='domain=$domain',
            group='first_char')

        if qr:
            chars = [str(i.first_char).upper() for i in qr]
            chars.sort()

        return (True, chars)
    except Exception as e:
        log_traceback()
        return (False, repr(e))
示例#15
0
def get_paged_domain_admins(conn,
                            domain,
                            include_global_admins=False,
                            columns=None,
                            current_page=1,
                            first_char=None):
    """Get all admins who have privilege to manage specified domain."""
    if columns:
        sql_what = ','.join(columns)
    else:
        sql_what = '*'

    if include_global_admins:
        sql_where = """username IN (
                       SELECT username FROM domain_admins
                       WHERE domain IN ('%s', 'ALL'))""" % domain
    else:
        sql_where = """username IN (
                       SELECT username FROM domain_admins
                       WHERE domain='%s')""" % domain

    if first_char:
        sql_where += ' AND username LIKE %s' % web.sqlquote(
            first_char.lower() + '%')

    total = 0
    all_admins = []
    try:
        qr_total = conn.select('mailbox',
                               what='COUNT(username) AS total',
                               where=sql_where)

        if qr_total:
            total = qr_total[0].total or 0
            qr = conn.select('mailbox',
                             what=sql_what,
                             where=sql_where,
                             limit=settings.PAGE_SIZE_LIMIT,
                             offset=(current_page - 1) *
                             settings.PAGE_SIZE_LIMIT)

            for i in qr:
                all_admins += [i]

        return (True, {'total': total, 'records': all_admins})
    except Exception as e:
        log_traceback()
        return (False, repr(e))
示例#16
0
def __is_account_exists(account, account_type, conn=None) -> bool:
    """Check whether mail alias account exists."""
    if account_type == 'domain':
        if not iredutils.is_domain(account):
            return True

        account = account.lower()
    else:
        if not iredutils.is_email(account):
            return False

        account = iredutils.strip_mail_ext_address(account)

    # {<account_type: [(<sql-table>, <sql-column-name>), ...]}
    _maps = {
        "domain": [
            ("domain", "domain"),
            ("alias_domain", "alias_domain"),
        ],
        "user": [("mailbox", "username")],
        "alias": [("alias", "address")],
        "ml": [("maillists", "address")],
    }

    if account_type not in _maps:
        return False

    if not conn:
        _wrap = SQLWrap()
        conn = _wrap.conn

    try:
        for (_table, _column) in _maps[account_type]:
            qr = conn.select(_table,
                             vars={'account': account},
                             what=_column,
                             where='%s=$account' % _column,
                             limit=1)

            if qr:
                return True
    except:
        log_traceback()
        return False

    return False
示例#17
0
def filter_existing_domains(domains, conn=None):
    """
    Remove non-existing domains from given list of domains , return a
    dict of existing ones and non-existing ones.

    :param domains: list of domain names
    :param conn: ldap connection cursor
    """
    domains = list({str(v).lower() for v in domains if iredutils.is_domain(v)})

    exist = []
    nonexist = []

    if not domains:
        return {'exist': exist, 'nonexist': nonexist}

    if not conn:
        _wrap = LDAPWrap()
        conn = _wrap.conn

    _filter = '(&(objectClass=mailDomain)'
    _filter += '(|'
    for d in domains:
        _filter += '(domainName={})(domainAliasName={})'.format(d, d)

    _filter += '))'

    try:
        qr = conn.search_s(settings.ldap_basedn,
                           ldap.SCOPE_ONELEVEL,
                           _filter,
                           ['domainName', 'domainAliasName'])

        if not qr:
            # All are not exist
            nonexist = domains
        else:
            for (_dn, _ldif) in qr:
                _ldif = iredutils.bytes2str(_ldif)
                exist += _ldif.get('domainName', []) + _ldif.get('domainAliasName', [])

            nonexist = [v for v in domains if v not in exist]
    except:
        log_traceback()

    return {'exist': exist, 'nonexist': nonexist}
示例#18
0
def sum_all_allocated_domain_quota(admin=None,
                                   domains=None,
                                   listed_only=True,
                                   conn=None):
    """Sum all allocated quota of managed domains.

    (True, <inteter>) if success.
    (False, <error_reason>) if failed to sum.
    """
    num = 0

    if not admin:
        admin = session.get('username')

    if not conn:
        _wrap = SQLWrap()
        conn = _wrap.conn

    if not domains:
        qr = get_managed_domains(conn=conn,
                                 admin=admin,
                                 domain_name_only=True,
                                 listed_only=listed_only)
        if qr[0]:
            domains = qr[1]

    if not domains:
        return (True, num)

    # Get allocated quota
    try:
        qr = conn.select('domain',
                         vars={'domains': domains},
                         what='maxquota',
                         where='domain IN $domains')

        if qr:
            for i in qr:
                if i.maxquota:
                    num += i.maxquota

        return (True, int(num))
    except Exception as e:
        log_traceback()
        return (False, repr(e))
示例#19
0
def get_all_admins(columns=None, email_only=False, conn=None):
    """List all admins. Return (True, [records])."""
    sql_what = '*'
    if columns:
        sql_what = ','.join(columns)

    records = []
    try:
        if not conn:
            _wrap = SQLWrap()
            conn = _wrap.conn

        # standalone admin accounts
        qr = conn.select('admin', what=sql_what, order='username')

        for i in qr:
            records += [i]

        # mail users with admin privileges
        qr = conn.select('mailbox',
                         what=sql_what,
                         where='isadmin=1 OR isglobaladmin=1',
                         order='username')

        for i in qr:
            records += [i]

        if email_only:
            _emails = []

            for rcd in records:
                _mail = str(rcd.username).lower()
                if _mail not in _emails:
                    _emails += [_mail]

            _emails.sort()

            return (True, _emails)

        return (True, records)
    except Exception as e:
        log_traceback()
        return (False, repr(e))
示例#20
0
def get_all_global_admins(conn=None):
    admins = []

    try:
        if not conn:
            _wrap = SQLWrap()
            conn = _wrap.conn

        qr = conn.select('domain_admins',
                         what='username',
                         where="domain='ALL'")

        for r in qr:
            admins += [str(r.username).lower()]

        admins.sort()
        return (True, admins)
    except Exception as e:
        log_traceback()
        return (False, repr(e))
示例#21
0
def get_paged_admins(conn, cur_page=1):
    # Get current page.
    cur_page = int(cur_page)

    sql_limit = ''
    if cur_page > 0:
        sql_limit = 'LIMIT %d OFFSET %d' % (
            settings.PAGE_SIZE_LIMIT,
            (cur_page - 1) * settings.PAGE_SIZE_LIMIT,
        )

    try:
        # Get number of total accounts
        total = num_admins(conn) + num_user_admins(conn)

        # Get records
        # Separate admins
        qr_admins = conn.query("""
            SELECT name, username, language, active
              FROM admin
          ORDER BY username ASC
            %s
            """ % (sql_limit))

        qr_user_admins = conn.query("""
            SELECT name, username, language, active, isadmin, isglobaladmin
              FROM mailbox
             WHERE (isadmin=1 OR isglobaladmin=1)
          ORDER BY username ASC
            %s
            """ % (sql_limit))
        return (True, {
            'total': total,
            'records': list(qr_admins) + list(qr_user_admins)
        })
    except Exception as e:
        log_traceback()
        return (False, repr(e))
示例#22
0
def get_first_char_of_all_accounts(domain, account_type, conn=None):
    """Get a list of first character of mail addresses under given domain.

    @domain - must be a valid domain name.
    @account_type - must be one of: user, maillist, ml, alias.
    @conn - ldap connection cursor.
    """
    if not iredutils.is_domain(domain):
        return []

    if not conn:
        _wrap = LDAPWrap()
        conn = _wrap.conn

    if account_type == 'user':
        _filter = '(objectClass=mailUser)'
        _dn = ldaputils.rdn_value_to_ou_users_dn(domain)
    else:
        return []

    chars = set()
    try:
        qr = conn.search_s(_dn,
                           ldap.SCOPE_ONELEVEL,
                           _filter,
                           ['mail'])

        for (_dn, _ldif) in qr:
            _ldif = iredutils.bytes2str(_ldif)
            _char = _ldif['mail'][0][0]
            chars.add(_char.upper())

        chars = list(chars)
        chars.sort()
    except:
        log_traceback()

    return chars
示例#23
0
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))
示例#24
0
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, )
示例#25
0
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))
示例#26
0
def __num_allocated_accounts(admin=None,
                             domains=None,
                             conn=None,
                             listed_only=False):
    """Count allocated users/aliases/lists of all managed domains."""
    num = {'users': 0, 'aliases': 0, 'lists': 0}

    if not admin:
        admin = session.get('username')

    if not conn:
        _wrap = SQLWrap()
        conn = _wrap.conn

    if domains:
        domains = [str(d).lower() for d in domains if iredutils.is_domain(d)]
    else:
        qr = get_managed_domains(conn=conn,
                                 admin=admin,
                                 domain_name_only=True,
                                 listed_only=listed_only)
        if qr[0]:
            domains = qr[1]

    if not domains:
        return num

    sql_vars = {'admin': admin, 'domains': domains}

    try:
        if sql_lib_general.is_global_admin(admin=admin, conn=conn):
            sql_what = 'SUM(mailboxes) AS mailboxes, SUM(aliases) AS aliases, SUM(maillists) AS maillists'

            if domains:
                qr = conn.select('domain',
                                 vars=sql_vars,
                                 what=sql_what,
                                 where='domain IN $domains')
            else:
                qr = conn.select('domain', what=sql_what)
        else:
            sql_what = 'SUM(domain.mailboxes) AS mailboxes, SUM(domain.aliases) AS aliases, SUM(domain.maillists) as maillists'

            sql_append_where = ''
            if domains:
                sql_append_where = 'AND domain.domain IN %s' % web.sqlquote(
                    domains)

            qr = conn.query("""
                            SELECT %s
                            FROM domain
                            LEFT JOIN domain_admins ON (domain.domain = domain_admins.domain)
                            WHERE domain_admins.username=$admin %s
                            """ % (sql_what, sql_append_where),
                            vars=sql_vars)

        if qr:
            _qr = list(qr)[0]
            num['users'] = int(_qr.mailboxes) or 0
    except:
        log_traceback()

    return num
示例#27
0
def filter_existing_emails(mails, account_type=None, conn=None):
    """
    Remove non-existing addresses in given list, return a list of existing ones.

    :param mails: list of email addresses
    :param account_type: user, alias, maillist.
    :param conn: sql connection cursor
    """
    exist = []
    nonexist = []

    mails = [i for i in mails if iredutils.is_email(i)]

    if not mails:
        return {'exist': exist, 'nonexist': nonexist}

    # A dict with email addresses without and with mail extension.
    d = {}
    for i in mails:
        _addr_without_ext = iredutils.strip_mail_ext_address(i)
        d[_addr_without_ext] = i

    emails_without_ext = list(d.keys())

    # {<account_type>: {'table': <sql_table_name>, 'column': <sql_column_name>}}
    _tbl_column_maps = {
        'user': [("forwardings", "address"), ("mailbox", "username")],
        'alias': [("alias", "address")],
        'maillist': [("maillists", "address")],
    }

    if not conn:
        _wrap = SQLWrap()
        conn = _wrap.conn

    try:
        _tbl_and_columns = []
        if account_type:
            _tbl_and_columns += _tbl_column_maps[account_type]
        else:
            for v in list(_tbl_column_maps.values()):
                _tbl_and_columns += v

        for (_table, _column) in _tbl_and_columns:
            # Removing verified addresses to query less values for better SQL
            # query performance.
            _pending_emails = [i for i in emails_without_ext if i not in exist]
            if not _pending_emails:
                break

            qr = conn.select(_table,
                             vars={'mails': _pending_emails},
                             what='%s' % _column,
                             where='%s IN $mails' % _column,
                             group='%s' % _column)

            if qr:
                for row in qr:
                    _addr = str(row[_column]).lower()
                    exist.append(d[_addr])

        exist = list(set(exist))
        nonexist = [d[k] for k in d if k not in exist]
    except:
        log_traceback()

    return {'exist': exist, 'nonexist': nonexist}