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
def xhr_list_domains(self): sess = DbSession() qry = sess.query(Domain.id, Domain.name).order_by( Domain.name) opts = "\n".join(['<option value="{0}">{1}</option>'.format( markupsafe.escape(x[0]), markupsafe.escape(x[1])) for x in qry]) return "<select>\n" + opts + "\n</select>"
def xhr_create_rolemember(self): log = pysite.lib.JsonResp() principal_ids = [int(x) for x in self.request.POST.getall( 'principal_ids[]') if int(x) != 0] if not principal_ids: log.error('No principals selected') return log.resp role_ids = [int(x) for x in self.request.POST.getall( 'role_ids[]') if int(x) != 0] if not role_ids: log.error('No roles selected') return log.resp sess = DbSession() try: for rid in role_ids: for pid in principal_ids: # XXX This is not atomic! if not sess.query(RoleMember.id).filter( sa.and_(RoleMember.principal_id == pid, RoleMember.role_id == rid)).all(): manager.create_rolemember(dict( owner=self.request.user.uid, principal_id=pid, role_id=rid )) except (StatementError) as exc: log.fatal(str(exc)) return log.resp else: log.ok("{0} principals added to {1} roles" .format(len(principal_ids), len(role_ids))) return log.resp
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
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
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
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
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
def xhr_list_tenants(self): sess = DbSession() qry = sess.query(Principal.id, Principal.display_name).order_by( Principal.display_name) opts = "\n".join(['<option value="{0}">{1}</option>'.format( markupsafe.escape(x[0]), markupsafe.escape(x[1])) for x in qry]) return "<select>\n" + opts + "\n</select>"
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()
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()
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()
def load_by_principal(principal): """ Loads a princpal instance by principal. """ sess = DbSession() try: p = sess.query(Principal).filter( Principal.principal == principal).one() except NoResultFound: raise AuthError('Principal not found') return p
def _build_browse_queries(self, request, grid): sess = DbSession() vw_browse = pysite.vmailmgr.models.get_vw_alias_browse() # Build query for count and apply filter qry_total = sess.query(sa.func.count(vw_browse.c.id)) qry_total = grid.apply_filter(qry_total) qry = sess.query(vw_browse) # Setup field names for initial order and primary key if not grid.order_field: grid.order_field = 'id' # Apply filter, order and limit from grid to qry. # Grid must have been initialised with order_field for this. qry = grid.apply_filter(qry) qry = grid.apply_order(qry) qry = grid.apply_limit(qry) return (qry, qry_total, )
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
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
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
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
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()
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()
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()
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
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