Example #1
0
def get_metadata_files(draft):
    data = draft.registration_metadata
    for q, question in get_file_questions('prereg-prize.json'):
        if not isinstance(data[q]['value'], dict):
            for i, file_info in enumerate(data[q]['extra']):
                provider = file_info['data']['provider']
                if provider != 'osfstorage':
                    raise Http404(
                        'File does not exist in OSFStorage ({}: {})'.format(
                            q, question
                        ))
                file_guid = file_info.get('fileId')
                if not file_guid:
                    node = Node.load(file_info.get('nodeId'))
                    path = file_info['data'].get('path')
                    item = BaseFileNode.resolve_class(
                        provider,
                        BaseFileNode.FILE
                    ).get_or_create(node, path)
                    file_guid = item.get_guid(create=True)._id
                    data[q]['extra'][i]['fileId'] = file_guid
                    draft.update_metadata(data)
                    draft.save()
                else:
                    item = BaseFileNode.load(file_info['data']['path'].replace('/', ''))
                if item is None:
                    raise Http404(
                        'File with guid "{}" in "{}" does not exist'.format(
                            file_guid, question
                        ))
                yield item
            continue
        for i, file_info in enumerate(data[q]['value']['uploader']['extra']):
            provider = file_info['data']['provider']
            if provider != 'osfstorage':
                raise Http404(
                    'File does not exist in OSFStorage ({}: {})'.format(
                        q, question
                    ))
            file_guid = file_info.get('fileId')
            if not file_guid:
                node = Node.load(file_info.get('nodeId'))
                path = file_info['data'].get('path')
                item = BaseFileNode.resolve_class(
                    provider,
                    BaseFileNode.FILE
                ).get_or_create(node, path)
                file_guid = item.get_guid(create=True)._id
                data[q]['value']['uploader']['extra'][i]['fileId'] = file_guid
                draft.update_metadata(data)
                draft.save()
            else:
                item = BaseFileNode.load(file_info['data']['path'].replace('/', ''))
            if item is None:
                raise Http404(
                    'File with guid "{}" in "{}" does not exist'.format(
                        file_guid, question
                    ))
            yield item
Example #2
0
def get_metadata_files(draft):
    data = draft.registration_metadata
    for q, question in get_file_questions('prereg-prize.json'):
        if not isinstance(data[q]['value'], dict):
            for i, file_info in enumerate(data[q]['extra']):
                provider = file_info['data']['provider']
                if provider != 'osfstorage':
                    raise Http404(
                        'File does not exist in OSFStorage ({}: {})'.format(
                            q, question
                        ))
                file_guid = file_info.get('fileId')
                if not file_guid:
                    node = Node.load(file_info.get('nodeId'))
                    path = file_info['data'].get('path')
                    item = BaseFileNode.resolve_class(
                        provider,
                        BaseFileNode.FILE
                    ).get_or_create(node, path)
                    file_guid = item.get_guid(create=True)._id
                    data[q]['extra'][i]['fileId'] = file_guid
                    draft.update_metadata(data)
                    draft.save()
                else:
                    item = BaseFileNode.load(file_info['data']['path'].replace('/', ''))
                if item is None:
                    raise Http404(
                        'File with guid "{}" in "{}" does not exist'.format(
                            file_guid, question
                        ))
                yield item
            continue
        for i, file_info in enumerate(data[q]['value']['uploader']['extra']):
            provider = file_info['data']['provider']
            if provider != 'osfstorage':
                raise Http404(
                    'File does not exist in OSFStorage ({}: {})'.format(
                        q, question
                    ))
            file_guid = file_info.get('fileId')
            if not file_guid:
                node = Node.load(file_info.get('nodeId'))
                path = file_info['data'].get('path')
                item = BaseFileNode.resolve_class(
                    provider,
                    BaseFileNode.FILE
                ).get_or_create(node, path)
                file_guid = item.get_guid(create=True)._id
                data[q]['value']['uploader']['extra'][i]['fileId'] = file_guid
                draft.update_metadata(data)
                draft.save()
            else:
                item = BaseFileNode.load(file_info['data']['path'].replace('/', ''))
            if item is None:
                raise Http404(
                    'File with guid "{}" in "{}" does not exist'.format(
                        file_guid, question
                    ))
            yield item
Example #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.objects.filter(root_target___id=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()
Example #4
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()
Example #5
0
def addon_view_or_download_file(auth, path, provider, **kwargs):
    extras = request.args.to_dict()
    extras.pop('_', None)  # Clean up our url params a bit
    action = extras.get('action', 'view')
    guid = kwargs.get('guid')
    guid_target = getattr(Guid.load(guid), 'referent', None)
    target = guid_target or kwargs.get('node') or kwargs['project']

    provider_safe = markupsafe.escape(provider)
    path_safe = markupsafe.escape(path)

    if not path:
        raise HTTPError(http_status.HTTP_400_BAD_REQUEST)

    if hasattr(target, 'get_addon'):

        node_addon = target.get_addon(provider)

        if not isinstance(node_addon, BaseStorageAddon):
            object_text = markupsafe.escape(
                getattr(target, 'project_or_component', 'this object'))
            raise HTTPError(
                http_status.HTTP_400_BAD_REQUEST,
                data={
                    'message_short':
                    'Bad Request',
                    'message_long':
                    'The {} add-on containing {} is no longer connected to {}.'
                    .format(provider_safe, path_safe, object_text)
                })

        if not node_addon.has_auth:
            raise HTTPError(
                http_status.HTTP_401_UNAUTHORIZED,
                data={
                    'message_short':
                    'Unauthorized',
                    'message_long':
                    'The {} add-on containing {} is no longer authorized.'.
                    format(provider_safe, path_safe)
                })

        if not node_addon.complete:
            raise HTTPError(
                http_status.HTTP_400_BAD_REQUEST,
                data={
                    'message_short':
                    'Bad Request',
                    'message_long':
                    'The {} add-on containing {} is no longer configured.'.
                    format(provider_safe, path_safe)
                })

    savepoint_id = transaction.savepoint()
    file_node = BaseFileNode.resolve_class(provider,
                                           BaseFileNode.FILE).get_or_create(
                                               target, path)

    # Note: Cookie is provided for authentication to waterbutler
    # it is overriden to force authentication as the current user
    # the auth header is also pass to support basic auth
    version = file_node.touch(
        request.headers.get('Authorization'),
        **dict(extras, cookie=request.cookies.get(settings.COOKIE_NAME)))
    if version is None:
        # File is either deleted or unable to be found in the provider location
        # Rollback the insertion of the file_node
        transaction.savepoint_rollback(savepoint_id)
        if not file_node.pk:
            file_node = BaseFileNode.load(path)

            if not file_node:
                raise HTTPError(http_status.HTTP_404_NOT_FOUND,
                                data={
                                    'message_short':
                                    'File Not Found',
                                    'message_long':
                                    'The requested file could not be found.'
                                })

            if file_node.kind == 'folder':
                raise HTTPError(
                    http_status.HTTP_400_BAD_REQUEST,
                    data={
                        'message_short':
                        'Bad Request',
                        'message_long':
                        'You cannot request a folder from this endpoint.'
                    })

            # Allow osfstorage to redirect if the deep url can be used to find a valid file_node
            if file_node.provider == 'osfstorage' and not file_node.is_deleted:
                return redirect(
                    file_node.target.web_url_for('addon_view_or_download_file',
                                                 path=file_node._id,
                                                 provider=file_node.provider))
        return addon_deleted_file(target=target,
                                  file_node=file_node,
                                  path=path,
                                  **kwargs)
    else:
        transaction.savepoint_commit(savepoint_id)

    # TODO clean up these urls and unify what is used as a version identifier
    if request.method == 'HEAD':
        return make_response(('', http_status.HTTP_302_FOUND, {
            'Location':
            file_node.generate_waterbutler_url(
                **dict(extras,
                       direct=None,
                       version=version.identifier,
                       _internal=extras.get('mode') == 'render'))
        }))

    if action == 'download':
        format = extras.get('format')
        _, extension = os.path.splitext(file_node.name)
        # avoid rendering files with the same format type.
        if format and '.{}'.format(format.lower()) != extension.lower():
            return redirect('{}/export?format={}&url={}'.format(
                get_mfr_url(target, provider), format,
                quote(
                    file_node.generate_waterbutler_url(
                        **dict(extras,
                               direct=None,
                               version=version.identifier,
                               _internal=extras.get('mode') == 'render')))))
        return redirect(
            file_node.generate_waterbutler_url(
                **dict(extras,
                       direct=None,
                       version=version.identifier,
                       _internal=extras.get('mode') == 'render')))

    if action == 'get_guid':
        draft_id = extras.get('draft')
        draft = DraftRegistration.load(draft_id)
        if draft is None or draft.is_approved:
            raise HTTPError(http_status.HTTP_400_BAD_REQUEST,
                            data={
                                'message_short':
                                'Bad Request',
                                'message_long':
                                'File not associated with required object.'
                            })
        guid = file_node.get_guid(create=True)
        guid.referent.save()
        return dict(guid=guid._id)

    if len(request.path.strip('/').split('/')) > 1:
        guid = file_node.get_guid(create=True)
        return redirect(
            furl.furl('/{}/'.format(guid._id)).set(args=extras).url)
    if isinstance(target, Preprint):
        # Redirecting preprint file guids to the preprint detail page
        return redirect('/{}/'.format(target._id))

    return addon_view_file(auth, target, file_node, version)
Example #6
0
 def get_object(self, file_id):
     return BaseFileNode.load(file_id)
Example #7
0
def addon_view_or_download_file(auth, path, provider, **kwargs):
    extras = request.args.to_dict()
    extras.pop('_', None)  # Clean up our url params a bit
    action = extras.get('action', 'view')
    guid = kwargs.get('guid')
    guid_target = getattr(Guid.load(guid), 'referent', None)
    target = guid_target or kwargs.get('node') or kwargs['project']

    provider_safe = markupsafe.escape(provider)
    path_safe = markupsafe.escape(path)

    if not path:
        raise HTTPError(httplib.BAD_REQUEST)

    if hasattr(target, 'get_addon'):

        node_addon = target.get_addon(provider)

        if not isinstance(node_addon, BaseStorageAddon):
            object_text = markupsafe.escape(getattr(target, 'project_or_component', 'this object'))
            raise HTTPError(httplib.BAD_REQUEST, data={
                'message_short': 'Bad Request',
                'message_long': 'The {} add-on containing {} is no longer connected to {}.'.format(provider_safe, path_safe, object_text)
            })

        if not node_addon.has_auth:
            raise HTTPError(httplib.UNAUTHORIZED, data={
                'message_short': 'Unauthorized',
                'message_long': 'The {} add-on containing {} is no longer authorized.'.format(provider_safe, path_safe)
            })

        if not node_addon.complete:
            raise HTTPError(httplib.BAD_REQUEST, data={
                'message_short': 'Bad Request',
                'message_long': 'The {} add-on containing {} is no longer configured.'.format(provider_safe, path_safe)
            })

    savepoint_id = transaction.savepoint()
    file_node = BaseFileNode.resolve_class(provider, BaseFileNode.FILE).get_or_create(target, path)

    # Note: Cookie is provided for authentication to waterbutler
    # it is overriden to force authentication as the current user
    # the auth header is also pass to support basic auth
    version = file_node.touch(
        request.headers.get('Authorization'),
        **dict(
            extras,
            cookie=request.cookies.get(settings.COOKIE_NAME)
        )
    )
    if version is None:
        # File is either deleted or unable to be found in the provider location
        # Rollback the insertion of the file_node
        transaction.savepoint_rollback(savepoint_id)
        if not file_node.pk:
            file_node = BaseFileNode.load(path)

            if file_node.kind == 'folder':
                raise HTTPError(httplib.BAD_REQUEST, data={
                    'message_short': 'Bad Request',
                    'message_long': 'You cannot request a folder from this endpoint.'
                })

            # Allow osfstorage to redirect if the deep url can be used to find a valid file_node
            if file_node and file_node.provider == 'osfstorage' and not file_node.is_deleted:
                return redirect(
                    file_node.target.web_url_for('addon_view_or_download_file', path=file_node._id, provider=file_node.provider)
                )
        return addon_deleted_file(target=target, file_node=file_node, path=path, **kwargs)
    else:
        transaction.savepoint_commit(savepoint_id)

    # TODO clean up these urls and unify what is used as a version identifier
    if request.method == 'HEAD':
        return make_response(('', httplib.FOUND, {
            'Location': file_node.generate_waterbutler_url(**dict(extras, direct=None, version=version.identifier, _internal=extras.get('mode') == 'render'))
        }))

    if action == 'download':
        format = extras.get('format')
        _, extension = os.path.splitext(file_node.name)
        # avoid rendering files with the same format type.
        if format and '.{}'.format(format.lower()) != extension.lower():
            return redirect('{}/export?format={}&url={}'.format(get_mfr_url(target, provider), format, urllib.quote(file_node.generate_waterbutler_url(
                **dict(extras, direct=None, version=version.identifier, _internal=extras.get('mode') == 'render')
            ))))
        return redirect(file_node.generate_waterbutler_url(**dict(extras, direct=None, version=version.identifier, _internal=extras.get('mode') == 'render')))

    if action == 'get_guid':
        draft_id = extras.get('draft')
        draft = DraftRegistration.load(draft_id)
        if draft is None or draft.is_approved:
            raise HTTPError(httplib.BAD_REQUEST, data={
                'message_short': 'Bad Request',
                'message_long': 'File not associated with required object.'
            })
        guid = file_node.get_guid(create=True)
        guid.referent.save()
        return dict(guid=guid._id)

    if len(request.path.strip('/').split('/')) > 1:
        guid = file_node.get_guid(create=True)
        return redirect(furl.furl('/{}/'.format(guid._id)).set(args=extras).url)
    if isinstance(target, Preprint):
        # Redirecting preprint file guids to the preprint detail page
        return redirect('/{}/'.format(target._id))

    return addon_view_file(auth, target, file_node, version)
Example #8
0
 def get_object(self, file_id):
     return BaseFileNode.load(file_id)
Example #9
0
def view_file(request, node_id, provider, file_id):
    fp = BaseFileNode.load(file_id)
    wb_url = fp.generate_waterbutler_url()
    return redirect(wb_url)
Example #10
0
def view_file(request, node_id, provider, file_id):
    fp = BaseFileNode.load(file_id)
    wb_url = fp.generate_waterbutler_url()
    return redirect(wb_url)