def iter_permissions(folder, user): """Iterator returning permissions settings on folder and its subfolders tree.""" if not security.has_permission(user, "manage", folder, inherit=True): return community = folder.path local_roles = frozenset(folder.get_local_roles_assignments()) inherited_roles = frozenset( folder.get_inherited_roles_assignments() if folder.inherit_security else [] ) result = {} for principal, role in local_roles | inherited_roles: data = result.setdefault((principal, role), {}) data["local"] = (principal, role) in local_roles data["inherit"] = (principal, role) in inherited_roles def _sort_key(item): """Sorts by name, groups first.""" principal = item[0][0] is_user = isinstance(principal, User) item_key = [is_user] # type: List[Any] if is_user: last_name = principal.last_name or "" first_name = principal.first_name or "" item_key.append(last_name.lower()) item_key.append(first_name.lower()) else: item_key.append(principal.name) return item_key for (p, role), data in sorted(result.items(), key=_sort_key): is_user = isinstance(p, User) has_access = False if is_user else "*" identifier = p.email if is_user else "* Group *" first_name = p.first_name if is_user else "-" last_name = p.last_name if is_user else p.name local = data["local"] inherit = data["inherit"] yield ( has_access, identifier, first_name, last_name, role, local, inherit, community, ) subfolders = ( f for f in folder.subfolders if security.has_permission(user, "manage", folder) ) for subfolder in subfolders: for permission in iter_permissions(subfolder, user): yield permission
def iter_permissions(folder, user): """Iterator returning permissions settings on folder and its subfolders tree.""" if not security.has_permission(user, "manage", folder, inherit=True): return community = folder.path local_roles = frozenset(folder.get_local_roles_assignments()) inherited_roles = frozenset((folder.get_inherited_roles_assignments() if folder.inherit_security else [])) result = {} for principal, role in local_roles | inherited_roles: data = result.setdefault((principal, role), {}) data["local"] = (principal, role) in local_roles data["inherit"] = (principal, role) in inherited_roles def _sort_key(item): """Sorts by name, groups first.""" principal = item[0][0] is_user = isinstance(principal, User) item_key = [is_user] # type: List[Any] if is_user: last_name = principal.last_name or "" first_name = principal.first_name or "" item_key.append(last_name.lower()) item_key.append(first_name.lower()) else: item_key.append(principal.name) return item_key for (p, role), data in sorted(result.items(), key=_sort_key): is_user = isinstance(p, User) has_access = False if is_user else "*" identifier = p.email if is_user else "* Group *" first_name = p.first_name if is_user else "-" last_name = p.last_name if is_user else p.name local = data["local"] inherit = data["inherit"] yield ( has_access, identifier, first_name, last_name, role, local, inherit, community, ) subfolders = (f for f in folder.subfolders if security.has_permission(user, "manage", folder)) for subfolder in subfolders: for permission in iter_permissions(subfolder, user): yield permission
def has_permission(self, user, permission, obj): assert isinstance(permission, Permission) return security.has_permission(user, permission, obj, inherit=True)
def move_multiple(folder): folders, docs = get_selected_objects(folder) count_f = len(folders) count_d = len(docs) current_folder_url = url_for(folder) if not (count_f + count_d): flash(_('Move elements: no elements selected.'), 'info') return redirect(current_folder_url) try: target_folder_id = int(request.form.get('target-folder')) except ValueError: flash(_('Move elements: no destination folder selected. Aborted.'), 'error') return redirect(current_folder_url) target_folder = repository.get_folder_by_id(target_folder_id) if folder == target_folder: flash( _('Move elements: source and destination folder are identical,' ' nothing done.'), 'error') return redirect(current_folder_url) if not security.has_permission(g.user, 'write', folder, inherit=True): # this should not happen: this is just defensive programming flash(_('You are not allowed to move elements from this folder'), 'error') return redirect(current_folder_url) if not security.has_permission( g.user, 'write', target_folder, inherit=True): flash( _('You are not allowed to write in folder "{folder}"').format( folder=target_folder.title), 'error') return redirect(current_folder_url) for item in itertools.chain(folders, docs): # FIXME: maybe too brutal check_write_access(item) # verify we are not trying to move a folder inside itself or one of its # descendants f = target_folder while f: if f in folders: flash( _('Move elements: destination folder is included in moved ' 'elements. Moved nothing.'), 'error') return redirect(url_for(folder)) f = f.parent exist_in_dest = [] for item in itertools.chain(folders, docs): try: with db.session.begin_nested(): item.parent = target_folder except sa.exc.IntegrityError: exist_in_dest.append(item) if exist_in_dest: # items existing in destination: cancel operation db.session.rollback() msg = _('Move elements: canceled, some elements exists in destination ' 'folder: {elements}') elements = ', '.join('"{}"'.format(i.title) for i in exist_in_dest) flash(msg.format(elements=elements), 'error') return redirect(current_folder_url) db.session.commit() msg_f = (_n('1 folder', '{count} folders', count_f) if count_f else _('0 folder')).format(count=count_f) msg_d = (_n('1 document', '{count} documents', count_d) if count_d else _('0 document')).format(count=count_d) msg = _('{folders} and {documents} moved to {target}').format( folders=msg_f, documents=msg_d, target=target_folder.title) flash(msg, 'success') return redirect(url_for(folder))
def can_delete(self, entity): """ True if user can delete attachments """ return security.has_permission(current_user, WRITE, obj=entity)
def can_edit(self, entity): """ True if user can edit attachments on entity """ return security.has_permission(current_user, WRITE, obj=entity)
def can_view(self, entity): """ True if user can view attachments on entity """ return security.has_permission(current_user, READ, obj=entity)
def can_create(self, entity): """True if user can add attachments.""" return security.has_permission(current_user, WRITE, obj=entity)
def has_permission(self, user, permission, obj): return security.has_permission(user, permission, obj, inherit=True)
def move_multiple(folder: Folder) -> Response: folders, docs = get_selected_objects(folder) objects = folders + docs count_f = len(folders) count_d = len(docs) current_folder_url = url_for(folder) if not (count_f + count_d): flash(_("Move elements: no elements selected."), "info") return redirect(current_folder_url) try: target_folder_id = int(request.form["target-folder"]) except ValueError: flash(_("Move elements: no destination folder selected. Aborted."), "error") return redirect(current_folder_url) target_folder = repository.get_folder_by_id(target_folder_id) if folder == target_folder: flash( _( "Move elements: source and destination folder are identical," " nothing done." ), "error", ) return redirect(current_folder_url) if not security.has_permission(current_user, "write", folder, inherit=True): # this should not happen: this is just defensive programming flash(_("You are not allowed to move elements from this folder"), "error") return redirect(current_folder_url) if not security.has_permission(current_user, "write", target_folder, inherit=True): flash( _('You are not allowed to write in folder "{folder}"').format( folder=target_folder.title ), "error", ) return redirect(current_folder_url) for item in objects: # FIXME: maybe too brutal check_write_access(item) # verify we are not trying to move a folder inside itself or one of its # descendants f = target_folder while f: if f in folders: flash( _( "Move elements: destination folder is included in moved " "elements. Moved nothing." ), "error", ) return redirect(url_for(folder)) f = f.parent exist_in_dest = objects_which_exist_in_dest(objects, target_folder) if exist_in_dest: # items existing in destination: cancel operation db.session.rollback() msg = _( "Move elements: canceled, some elements exists in destination " "folder: {elements}" ) elements = ", ".join(f'"{i.title}"' for i in exist_in_dest) flash(msg.format(elements=elements), "error") return redirect(current_folder_url) db.session.commit() msg_f = ( _n("1 folder", "{count} folders", count_f) if count_f else _("0 folder") ).format(count=count_f) msg_d = ( _n("1 document", "{count} documents", count_d) if count_d else _("0 document") ).format(count=count_d) msg = _("{folders} and {documents} moved to {target}").format( folders=msg_f, documents=msg_d, target=target_folder.title ) flash(msg, "success") return redirect(url_for(folder))
def move_multiple(folder): # type: (Folder) -> Response folders, docs = get_selected_objects(folder) objects = folders + docs count_f = len(folders) count_d = len(docs) current_folder_url = url_for(folder) if not (count_f + count_d): flash(_("Move elements: no elements selected."), "info") return redirect(current_folder_url) try: target_folder_id = int(request.form.get("target-folder")) except ValueError: flash(_("Move elements: no destination folder selected. Aborted."), "error") return redirect(current_folder_url) target_folder = repository.get_folder_by_id(target_folder_id) if folder == target_folder: flash( _("Move elements: source and destination folder are identical," " nothing done."), "error", ) return redirect(current_folder_url) if not security.has_permission(current_user, "write", folder, inherit=True): # this should not happen: this is just defensive programming flash(_("You are not allowed to move elements from this folder"), "error") return redirect(current_folder_url) if not security.has_permission( current_user, "write", target_folder, inherit=True): flash( _('You are not allowed to write in folder "{folder}"').format( folder=target_folder.title), "error", ) return redirect(current_folder_url) for item in objects: # FIXME: maybe too brutal check_write_access(item) # verify we are not trying to move a folder inside itself or one of its # descendants f = target_folder while f: if f in folders: flash( _("Move elements: destination folder is included in moved " "elements. Moved nothing."), "error", ) return redirect(url_for(folder)) f = f.parent exist_in_dest = objects_which_exist_in_dest(objects, target_folder) if exist_in_dest: # items existing in destination: cancel operation db.session.rollback() msg = _("Move elements: canceled, some elements exists in destination " "folder: {elements}") elements = ", ".join('"{}"'.format(i.title) for i in exist_in_dest) flash(msg.format(elements=elements), "error") return redirect(current_folder_url) db.session.commit() msg_f = (_n("1 folder", "{count} folders", count_f) if count_f else _("0 folder")).format(count=count_f) msg_d = (_n("1 document", "{count} documents", count_d) if count_d else _("0 document")).format(count=count_d) msg = _("{folders} and {documents} moved to {target}").format( folders=msg_f, documents=msg_d, target=target_folder.title) flash(msg, "success") return redirect(url_for(folder))
def has_permission(self, user, permission, obj): assert isinstance(permission, Permission) return security.has_permission(user, permission, obj, inherit=True)
def can_create(self, entity): """True if user can add attachments.""" return security.has_permission(current_user, WRITE, obj=entity)