Ejemplo n.º 1
0
def addon_delete_file_node(self, node, user, event_type, payload):
    """ Get addon BaseFileNode(s), move it into the TrashedFileNode collection
    and remove it from StoredFileNode.

    Required so that the guids of deleted addon files are not re-pointed when an
    addon file or folder is moved or renamed.
    """
    if event_type == 'file_removed' and payload.get('provider', None) != 'osfstorage':
        provider = payload['provider']
        path = payload['metadata']['path']
        materialized_path = payload['metadata']['materialized']
        if path.endswith('/'):
            folder_children = BaseFileNode.resolve_class(provider, BaseFileNode.ANY).objects.filter(
                provider=provider,
                node=node,
                _materialized_path__startswith=materialized_path
            )
            for item in folder_children:
                if item.kind == 'file' and not TrashedFileNode.load(item._id):
                    item.delete(user=user)
                elif item.kind == 'folder':
                    BaseFileNode.remove_one(item)
        else:
            try:
                file_node = BaseFileNode.resolve_class(provider, BaseFileNode.FILE).objects.get(
                    node=node,
                    _materialized_path=materialized_path
                )
            except BaseFileNode.DoesNotExist:
                file_node = None

            if file_node and not TrashedFileNode.load(file_node._id):
                file_node.delete(user=user)
Ejemplo n.º 2
0
    def get_file_guids(cls, materialized_path, provider, node=None):
        guids = []
        path = materialized_path.strip('/')
        file_obj = cls.load(path)
        if not file_obj:
            file_obj = TrashedFileNode.load(path)

        # At this point, file_obj may be an OsfStorageFile, an OsfStorageFolder, or a
        # TrashedFileNode. TrashedFileNodes do not have *File and *Folder subclasses, since
        # only osfstorage trashes folders. To search for children of TrashFileNodes
        # representing ex-OsfStorageFolders, we will reimplement the `children` method of the
        # Folder class here.
        if not file_obj.is_file:
            children = []
            if isinstance(file_obj, TrashedFileNode):
                children = file_obj.trashed_children.all()
            else:
                children = file_obj.children

            for item in children:
                guids.extend(cls.get_file_guids(item.path, provider, node=node))
        else:
            guid = file_obj.get_guid()
            if guid:
                guids.append(guid._id)

        return sorted(guids)
Ejemplo n.º 3
0
def update_file_guid_referent(self, node, event_type, payload, user=None):
    if event_type not in ('addon_file_moved', 'addon_file_renamed'):
        return  # Nothing to do

    source, destination = payload['source'], payload['destination']
    source_node, destination_node = Node.load(source['node']['_id']), Node.load(destination['node']['_id'])

    if source['provider'] in settings.ADDONS_BASED_ON_IDS:
        if event_type == 'addon_file_renamed':
            return  # Node has not changed and provider has not changed

        # Must be a move
        if source['provider'] == destination['provider'] and source_node == destination_node:
            return  # Node has not changed and provider has not changed

    file_guids = BaseFileNode.resolve_class(source['provider'], BaseFileNode.ANY).get_file_guids(
        materialized_path=source['materialized'] if source['provider'] != 'osfstorage' else source['path'],
        provider=source['provider'],
        node=source_node
    )

    for guid in file_guids:
        obj = Guid.load(guid)
        if source_node != destination_node and Comment.find(Q('root_target._id', 'eq', guid)).count() != 0:
            update_comment_node(guid, source_node, destination_node)

        if source['provider'] != destination['provider'] or source['provider'] != 'osfstorage':
            old_file = BaseFileNode.load(obj.referent._id)
            obj.referent = create_new_file(obj, source, destination, destination_node)
            obj.save()
            if old_file and not TrashedFileNode.load(old_file._id):
                old_file.delete()
Ejemplo n.º 4
0
def get_archived_from_url(node, file_node):
    if file_node.copied_from:
        trashed = TrashedFileNode.load(file_node.copied_from._id)
        if not trashed:
            return node.registered_from.web_url_for('addon_view_or_download_file', provider=file_node.provider, path=file_node.copied_from._id)
    return None
Ejemplo n.º 5
0
def addon_deleted_file(auth, target, error_type='BLAME_PROVIDER', **kwargs):
    """Shows a nice error message to users when they try to view a deleted file
    """
    # Allow file_node to be passed in so other views can delegate to this one
    file_node = kwargs.get('file_node') or TrashedFileNode.load(kwargs.get('trashed_id'))

    deleted_by, deleted_on = None, None
    if isinstance(file_node, TrashedFileNode):
        deleted_by = file_node.deleted_by
        deleted_by_guid = file_node.deleted_by._id if deleted_by else None
        deleted_on = file_node.deleted_on.strftime('%c') + ' UTC'
        if getattr(file_node, 'suspended', False):
            error_type = 'FILE_SUSPENDED'
        elif file_node.deleted_by is None or (auth.private_key and auth.private_link.anonymous):
            if file_node.provider == 'osfstorage':
                error_type = 'FILE_GONE_ACTOR_UNKNOWN'
            else:
                error_type = 'BLAME_PROVIDER'
        else:
            error_type = 'FILE_GONE'
    else:
        error_type = 'DONT_KNOW'

    file_path = kwargs.get('path', file_node.path)
    file_name = file_node.name or os.path.basename(file_path)
    file_name_title, file_name_ext = os.path.splitext(file_name)
    provider_full = settings.ADDONS_AVAILABLE_DICT[file_node.provider].full_name
    try:
        file_guid = file_node.get_guid()._id
    except AttributeError:
        file_guid = None

    format_params = dict(
        file_name=markupsafe.escape(file_name),
        deleted_by=markupsafe.escape(getattr(deleted_by, 'fullname', None)),
        deleted_on=markupsafe.escape(deleted_on),
        provider=markupsafe.escape(provider_full)
    )
    if deleted_by:
        format_params['deleted_by_guid'] = markupsafe.escape(deleted_by_guid)

    error_msg = ERROR_MESSAGES[error_type].format(**format_params)
    if isinstance(target, AbstractNode):
        error_msg += format_last_known_metadata(auth, target, file_node, error_type)
        ret = serialize_node(target, auth, primary=True)
        ret.update(rubeus.collect_addon_assets(target))
        ret.update({
            'error': error_msg,
            'urls': {
                'render': None,
                'sharejs': None,
                'mfr': get_mfr_url(target, file_node.provider),
                'profile_image': get_profile_image_url(auth.user, 25),
                'files': target.web_url_for('collect_file_trees'),
            },
            'extra': {},
            'size': 9966699,  # Prevent file from being edited, just in case
            'sharejs_uuid': None,
            'file_name': file_name,
            'file_path': file_path,
            'file_name_title': file_name_title,
            'file_name_ext': file_name_ext,
            'target_deleted': getattr(target, 'is_deleted', False),
            'version_id': None,
            'file_guid': file_guid,
            'file_id': file_node._id,
            'provider': file_node.provider,
            'materialized_path': file_node.materialized_path or file_path,
            'private': getattr(target.get_addon(file_node.provider), 'is_private', False),
            'file_tags': list(file_node.tags.filter(system=False).values_list('name', flat=True)) if not file_node._state.adding else [],  # Only access ManyRelatedManager if saved
            'allow_comments': file_node.provider in settings.ADDONS_COMMENTABLE,
        })
    else:
        # TODO - serialize deleted metadata for future types of deleted file targets
        ret = {'error': error_msg}

    return ret, httplib.GONE
Ejemplo n.º 6
0
def addon_deleted_file(auth, target, error_type='BLAME_PROVIDER', **kwargs):
    """Shows a nice error message to users when they try to view a deleted file
    """
    # Allow file_node to be passed in so other views can delegate to this one
    file_node = kwargs.get('file_node') or TrashedFileNode.load(
        kwargs.get('trashed_id'))

    deleted_by, deleted_on = None, None
    if isinstance(file_node, TrashedFileNode):
        deleted_by = file_node.deleted_by
        deleted_by_guid = file_node.deleted_by._id if deleted_by else None
        deleted_on = file_node.deleted_on.strftime('%c') + ' UTC'
        if getattr(file_node, 'suspended', False):
            error_type = 'FILE_SUSPENDED'
        elif file_node.deleted_by is None or (auth.private_key
                                              and auth.private_link.anonymous):
            if file_node.provider == 'osfstorage':
                error_type = 'FILE_GONE_ACTOR_UNKNOWN'
            else:
                error_type = 'BLAME_PROVIDER'
        else:
            error_type = 'FILE_GONE'
    else:
        error_type = 'DONT_KNOW'

    file_path = kwargs.get('path', file_node.path)
    file_name = file_node.name or os.path.basename(file_path)
    file_name_title, file_name_ext = os.path.splitext(file_name)
    provider_full = settings.ADDONS_AVAILABLE_DICT[
        file_node.provider].full_name
    try:
        file_guid = file_node.get_guid()._id
    except AttributeError:
        file_guid = None

    format_params = dict(file_name=markupsafe.escape(file_name),
                         deleted_by=markupsafe.escape(
                             getattr(deleted_by, 'fullname', None)),
                         deleted_on=markupsafe.escape(deleted_on),
                         provider=markupsafe.escape(provider_full))
    if deleted_by:
        format_params['deleted_by_guid'] = markupsafe.escape(deleted_by_guid)

    error_msg = ERROR_MESSAGES[error_type].format(**format_params)
    if isinstance(target, AbstractNode):
        error_msg += format_last_known_metadata(auth, target, file_node,
                                                error_type)
        ret = serialize_node(target, auth, primary=True)
        ret.update(rubeus.collect_addon_assets(target))
        ret.update({
            'error':
            error_msg,
            'urls': {
                'render': None,
                'sharejs': None,
                'mfr': get_mfr_url(target, file_node.provider),
                'profile_image': get_profile_image_url(auth.user, 25),
                'files': target.web_url_for('collect_file_trees'),
            },
            'extra': {},
            'size':
            9966699,  # Prevent file from being edited, just in case
            'sharejs_uuid':
            None,
            'file_name':
            file_name,
            'file_path':
            file_path,
            'file_name_title':
            file_name_title,
            'file_name_ext':
            file_name_ext,
            'target_deleted':
            getattr(target, 'is_deleted', False),
            'version_id':
            None,
            'file_guid':
            file_guid,
            'file_id':
            file_node._id,
            'provider':
            file_node.provider,
            'materialized_path':
            file_node.materialized_path or file_path,
            'private':
            getattr(target.get_addon(file_node.provider), 'is_private', False),
            'file_tags':
            list(
                file_node.tags.filter(system=False).values_list(
                    'name', flat=True)) if not file_node._state.adding else
            [],  # Only access ManyRelatedManager if saved
            'allow_comments':
            file_node.provider in settings.ADDONS_COMMENTABLE,
        })
    else:
        # TODO - serialize deleted metadata for future types of deleted file targets
        ret = {'error': error_msg}

    return ret, http_status.HTTP_410_GONE
Ejemplo n.º 7
0
def get_archived_from_url(node, file_node):
    if file_node.copied_from:
        trashed = TrashedFileNode.load(file_node.copied_from._id)
        if not trashed:
            return node.registered_from.web_url_for('addon_view_or_download_file', provider=file_node.provider, path=file_node.copied_from._id)
    return None
Ejemplo n.º 8
0
def addon_deleted_file(auth, node, error_type='BLAME_PROVIDER', **kwargs):
    """Shows a nice error message to users when they try to view a deleted file
    """
    # Allow file_node to be passed in so other views can delegate to this one
    file_node = kwargs.get('file_node') or TrashedFileNode.load(
        kwargs.get('trashed_id'))

    deleted_by, deleted_on = None, None
    if isinstance(file_node, TrashedFileNode):
        deleted_by = file_node.deleted_by
        deleted_by_guid = file_node.deleted_by._id if deleted_by else None
        deleted_on = file_node.deleted_on.strftime('%c') + ' UTC'
        if file_node.suspended:
            error_type = 'FILE_SUSPENDED'
        elif file_node.deleted_by is None:
            if file_node.provider == 'osfstorage':
                error_type = 'FILE_GONE_ACTOR_UNKNOWN'
            else:
                error_type = 'BLAME_PROVIDER'
        else:
            error_type = 'FILE_GONE'
    else:
        error_type = 'DONT_KNOW'

    file_path = kwargs.get('path', file_node.path)
    file_name = file_node.name or os.path.basename(file_path)
    file_name_title, file_name_ext = os.path.splitext(file_name)
    provider_full = settings.ADDONS_AVAILABLE_DICT[
        file_node.provider].full_name
    try:
        file_guid = file_node.get_guid()._id
    except AttributeError:
        file_guid = None

    format_params = dict(file_name=markupsafe.escape(file_name),
                         deleted_by=markupsafe.escape(deleted_by),
                         deleted_on=markupsafe.escape(deleted_on),
                         provider=markupsafe.escape(provider_full))
    if deleted_by:
        format_params['deleted_by_guid'] = markupsafe.escape(deleted_by_guid)

    ret = serialize_node(node, auth, primary=True)
    ret.update(rubeus.collect_addon_assets(node))
    ret.update({
        'error':
        ERROR_MESSAGES[error_type].format(**format_params),
        'urls': {
            'render': None,
            'sharejs': None,
            'mfr': settings.MFR_SERVER_URL,
            'gravatar': get_gravatar(auth.user, 25),
            'files': node.web_url_for('collect_file_trees'),
        },
        'extra': {},
        'size':
        9966699,  # Prevent file from being edited, just in case
        'sharejs_uuid':
        None,
        'file_name':
        file_name,
        'file_path':
        file_path,
        'file_name_title':
        file_name_title,
        'file_name_ext':
        file_name_ext,
        'version_id':
        None,
        'file_guid':
        file_guid,
        'file_id':
        file_node._id,
        'provider':
        file_node.provider,
        'materialized_path':
        file_node.materialized_path or file_path,
        'private':
        getattr(node.get_addon(file_node.provider), 'is_private', False),
        'file_tags':
        file_node.tags.filter(system=False).values_list('name', flat=True),
        'allow_comments':
        file_node.provider in settings.ADDONS_COMMENTABLE,
    })

    return ret, httplib.GONE