Exemple #1
0
def update_alias(data):
    """
    Updates an existing alias.

    Field ``domain``, if given, can be ID (int), name (str) or
    an instance of a Domain.

    Data fields:
    ``id``:     Required. ID of alias to update
    ``editor``: Required. ID of Principal
    ``mtime``:  Required

    :param data: Dict with data fields
    :returns: Instance of updated alias
    """
    if 'domain' in data:
        if not isinstance(data['domain'], Domain):
            data['domain'] = Domain.find_one(data['domain'])
        data['domain_id'] = data['domain'].id
        del data['domain']
    sess = DbSession()
    al = sess.query(Alias).filter(Alias.id==data['id']).one()
    for k, v in data.items():
        setattr(al, k, v)
    sess.flush()
    return al
Exemple #2
0
def update_principal(data):
    """
    Updates a principal.

    Data fields:
    ``id``:     Required. ID of principal to update
    ``editor``: Required
    ``mtime``:  Required

    :param data: Dict with data fields
    :returns: Instance of updated principal
    """
    # Make sure the password is encrypted
    if 'pwd' in data:
        if not data['pwd'].startswith(('{', '$')):
            data['pwd'] = pysite.security.pwd_context.encrypt(data['pwd'],
                PASSWORD_SCHEME)
    # Allow only lowercase principals
    if 'principal' in data:
        data['principal'] = data['principal'].lower()
    # Ditto email
    if 'email' in data:
        data['email'] = data['email'].lower()
    sess = DbSession()
    p = sess.query(Principal).filter(Principal.id == data['id']).one()
    for k, v in data.items():
        setattr(p, k, v)
    # If display_name is emptied, use principal
    if not p.display_name:
        p.display_name = p.principal
    sess.flush()
    return p
Exemple #3
0
def update_domain(data):
    """
    Updates a domain.

    Field ``tenant``, if given, can be ID (int), principal (str) or
    an instance of a Principal.

    Data fields:
    ``id``:     Required. ID of domain to update
    ``editor``: Required. ID of Principal
    ``mtime``:  Required

    :param data: Dict with data fields
    :returns: Instance of updated domain
    """
    # If 'tenant' is set, it may be ID, name or instance of a principal.
    if 'tenant' in data:
        if not isinstance(data['tenant'], Principal):
            data['tenant'] = Principal.find_one(data['tenant'])
        data['tenant_id'] = data['tenant'].id
        del data['tenant']
    sess = DbSession()
    dom = sess.query(Domain).filter(Domain.id==data['id']).one()
    for k, v in data.items():
        setattr(dom, k, v)
    sess.flush()
    return dom
Exemple #4
0
def create_domain(data):
    """
    Creates a new domain record.

    Field ``tenant`` can be ID (int), principal (str) or
    an instance of a Principal.

    Data fields:
    - ``owner``: Required
    - ``tenant``: Principal

    :param data: Dict with data fields
    :returns: Instance of created domain
    """
    # If 'tenant' is set, it may be ID, name or instance of a principal.
    if 'tenant' in data:
        if not isinstance(data['tenant'], Principal):
            data['tenant'] = Principal.find_one(data['tenant'])
        data['tenant_id'] = data['tenant'].id
        del data['tenant']
    # Set defaults
    if not 'max_mailboxes' in data:
        data['max_mailboxes'] = MAX_MAILBOXES
    if not 'max_aliases' in data:
        data['max_aliases'] = MAX_ALIASES
    if not 'quota' in data:
        data['quota'] = QUOTA
    
    sess = DbSession()
    dom = Domain()
    for k, v in data.items():
        setattr(dom, k, v)
    sess.add(dom)
    sess.flush() # to get ID of domain
    return dom
Exemple #5
0
def create_alias(data):
    """
    Creates a new alias record.

    Field ``domain`` can be ID (int), name (str) or
    an instance of a Domain.

    Data fields:
    - ``owner``: Required
    - ``domain``: Domain

    :param data: Dict with data fields
    :returns: Instance of created alias
    """
    if 'domain' in data:
        if not isinstance(data['domain'], Domain):
            data['domain'] = Domain.find_one(data['domain'])
        data['domain_id'] = data['domain'].id
        del data['domain']
    sess = DbSession()
    al = Alias()
    for k, v in data.items():
        setattr(al, k, v)
    sess.add(al)
    sess.flush() # to get ID of alias
    return al
Exemple #6
0
def update_mailbox(data):
    """
    Updates a mailbox.

    Field ``domain``, if given, can be ID (int), name (str) or
    an instance of a Domain.

    Data fields:
    ``id``:     Required. ID of mailbox to update
    ``editor``: Required. ID of Principal
    ``mtime``:  Required

    :param data: Dict with data fields
    :returns: Instance of updated mailbox
    """
    # If 'domain' is set, it may be ID, name or instance of a domain.
    if 'domain' in data:
        if not isinstance(data['domain'], Domain):
            data['domain'] = Domain.find_one(data['domain'])
        data['domain_id'] = data['domain'].id
        del data['domain']
    # Make sure the password is encrypted
    if 'pwd' in data and not data['pwd'].startswith('{'):
        data['pwd'] = pysite.security.pwd_context(data['pwd'],
            PASSWORD_SCHEME)

    sess = DbSession()
    mb = sess.query(Mailbox).filter(Mailbox.id==data['id']).one()
    for k, v in data.items():
        setattr(mb, k, v)
    sess.flush()
    return mb
Exemple #7
0
def delete_role(id):
    """
    Deletes a role.

    :param id: ID of role to delete
    """
    sess = DbSession()
    r = sess.query(Role).filter(Role.id == id).one()
    sess.delete(r)
    sess.flush()
Exemple #8
0
def delete_principal(id):
    """
    Deletes a principal.

    :param id: ID of principal to delete
    """
    sess = DbSession()
    p = sess.query(Principal).filter(Principal.id == id).one()
    sess.delete(p)
    sess.flush()
Exemple #9
0
def delete_mailbox(id_or_name):
    """
    Deletes a mailbox.

    :param id: ID of mailbox to delete
    """
    sess = DbSession()
    mb = Mailbox.find_one(id_or_name)
    sess.delete(mb)
    sess.flush()
Exemple #10
0
def delete_rolemember(id):
    """
    Deletes a rolemember.

    :param id: ID of rolemember to delete
    """
    sess = DbSession()
    rm = sess.query(RoleMember).filter(RoleMember.id == id).one()
    sess.delete(rm)
    sess.flush()
Exemple #11
0
def delete_domain(id_or_name):
    """
    Deletes a domain.

    :param id: ID of domain to delete
    """
    sess = DbSession()
    dom = Domain.find_one(id_or_name)
    sess.delete(dom)
    sess.flush()
Exemple #12
0
def delete_alias(id_or_name):
    """
    Deletes an alias.

    :param id: ID of alias to delete
    """
    sess = DbSession()
    al = Alias.find_one(id_or_name)
    sess.delete(al)
    sess.flush()
Exemple #13
0
def create_role(data):
    """
    Creates a new role record.

    Data fields:
    - ``owner``: Required
    :param data: Dict with data fields
    :returns: Instance of created role
    """
    sess = DbSession()
    r = Role()
    for k, v in data.items():
        setattr(r, k, v)
    sess.add(r)
    sess.flush()
    return r
Exemple #14
0
def update_role(data):
    """
    Updates a role.

    Data fields:
    ``id``:     Required. ID of role to update
    ``editor``: Required
    ``mtime``:  Required

    :param data: Dict with data fields
    :returns: Instance of updated role
    """
    sess = DbSession()
    r = sess.query(Role).filter(Role.id == data['id']).one()
    for k, v in data.items():
        setattr(r, k, v)
    sess.flush()
    return r
Exemple #15
0
def create_rolemember(data):
    """
    Creates a new rolemember record.

    Data fields:
    - ``owner``:        Required
    - ``principal_id``: Required
    - ``role_id``:      Required
    :param data: Dict with data fields
    :returns: Instance of created rolemember
    """
    sess = DbSession()
    rm = RoleMember()
    for k, v in data.items():
        setattr(rm, k, v)
    sess.add(rm)
    sess.flush()
    return rm
Exemple #16
0
def _login(filter, pwd):
    """
    Performs login.

    Called by the ``login_by...`` functions which initialise the filter.
    """
    filter.append(Principal.is_enabled == True)
    filter.append(Principal.is_blocked == False)
    sess = DbSession()
    try:
        p = sess.query(Principal).filter(and_(*filter)).one()
    except NoResultFound:
        raise AuthError('Principal not found')
    if not pysite.security.pwd_context.verify(pwd, p.pwd):
        raise AuthError('Wrong credentials')
    p.prev_login_time = p.login_time
    p.login_time = datetime.datetime.now()
    sess.flush()
    return p
Exemple #17
0
def create_principal(data):
    """
    Creates a new principal record.

    Data fields:
    - ``owner``: Required
    - ``roles``: Optional list of role names. Role 'users' is always
                 automatically set.
                 If we provide a value for roles that evaluates to False,
                 this account is not member of any role.

    :param data: Dict with data fields
    :returns: Instance of created principal
    """
    # Determine roles this principal will be member of.
    # Always at least 'users'.
    if 'roles' in data:
        if data['roles']:
            roles = set(data['roles'] + ['users'])
        else:
            roles = set()
        del data['roles']
    else:
        roles = ['users']
    # Make sure the password is encrypted
    if 'pwd' in data:
        if not data['pwd'].startswith(('{', '$')):
            data['pwd'] = pysite.security.pwd_context.encrypt(data['pwd'],
                PASSWORD_SCHEME)
    # If display_name is not explicitly set, use principal, thus
    # preserving its case (real principal will be stored lower case).
    if not 'display_name' in data:
        data['display_name'] = data['principal']
    # Allow only lowercase principals
    data['principal'] = data['principal'].lower()
    # Ditto email
    data['email'] = data['email'].lower()

    sess = DbSession()
    # Create principal
    p = Principal()
    for k, v in data.items():
        setattr(p, k, v)
    sess.add(p)
    sess.flush()  # to get ID of principal
    # Load/create the roles and memberships
    for name in roles:
        try:
            r = sess.query(Role).filter(Role.name == name).one()
        except NoResultFound:
            r = Role(name=name, owner=data['owner'])
            sess.add(r)
            sess.flush()
        rm = RoleMember(principal_id=p.id, role_id=r.id, owner=p.owner)
        sess.add(rm)
    sess.flush()
    return p
Exemple #18
0
def create_mailbox(data):
    """
    Creates a new mailbox record.

    Field ``domain`` can be ID (int), name (str) or
    an instance of a Domain.

    Data fields:
    - ``name``: Required. Str
    - ``owner``: Required. ID of Principal.
    - ``domain``: Required. Domain.
    - ``pwd``: Required. Password.

    :param data: Dict with data fields
    :returns: Instance of created mailbox
    """
    dom = None
    # If 'domain' is set, it may be ID, name or instance of a domain.
    # Load the appropriate domain and set 'domain_id'.
    if 'domain' in data:
        if not isinstance(data['domain'], Domain):
            data['domain'] = Domain.find_one(data['domain'])
        data['domain_id'] = data['domain'].id
        dom = data['domain']
        del data['domain']
    # 'domain' was not set, so load domain by its ID from 'domain_id'
    if not dom:
        dom = Domain.find_one(data['domain_id'])
    # Check that we are in limits
    if len(dom.mailboxes) >= dom.max_mailboxes:
        raise PySiteError("Maximum number of mailboxes reached.")
    # Make sure the password is encrypted
    if not data['pwd'].startswith('{'):
        data['pwd'] = pysite.security.pwd_context.encrypt(data['pwd'],
            PASSWORD_SCHEME)
    # Set defaults
    if not 'uid' in data:
        data['uid'] = UID
    if not 'gid' in data:
        data['gid'] = GID
    if not 'quota' in data:
        data['quota'] = dom.quota  # Default from domain!
    # Make sure, 'home_dir' is absolute path 
    d = data['home_dir'] if 'home_dir' in data else HOME_DIR
    d = d.format(root=ROOT_DIR, domain=dom.name, user=data['name'])
    if not d.startswith(os.path.sep):
        d = os.path.join(ROOT_DIR, d)
    data['home_dir'] = d
    # Make sure, 'mail_dir' is absolute path 
    d = data['mail_dir'] if 'mail_dir' in data else MAIL_DIR
    d = d.format(root=ROOT_DIR, domain=dom.name, user=data['name'])
    if not d.startswith(os.path.sep):
        d = os.path.join(ROOT_DIR, d)
    data['mail_dir'] = d

    sess = DbSession()
    mb = Mailbox()
    for k, v in data.items():
        setattr(mb, k, v)
    sess.add(mb)
    sess.flush() # to get ID of mailbox
    return mb