Exemplo n.º 1
0
    def test_delete_file_no_guid(self):
        child = self.node_settings.get_root().append_file('Test')

        assert_is(OsfStorageFileNode.load(child._id).guids.first(), None)

        with mock.patch('osf.models.files.apps.get_model') as get_model:
            child.delete()

            assert_is(get_model.called, False)

        assert_is(OsfStorageFileNode.load(child._id), None)
Exemplo n.º 2
0
    def test_delete_file_no_guid(self):
        child = self.node_settings.get_root().append_file('Test')

        assert_is(OsfStorageFileNode.load(child._id).guids.first(), None)

        with mock.patch('osf.models.files.apps.get_model') as get_model:
            child.delete()

            assert_is(get_model.called, False)

        assert_is(OsfStorageFileNode.load(child._id), None)
Exemplo n.º 3
0
    def test_delete_file_guids(self):
        child = self.node_settings.get_root().append_file('Test')
        guid = child.get_guid(create=True)

        assert_is_not(OsfStorageFileNode.load(child._id).guids.first(), None)

        with mock.patch('osf.models.files.apps.get_model') as get_model:
            child.delete()

            assert_is(get_model.called, True)
            assert_is(get_model('osf.Comment').objects.filter.called, True)

        assert_is(OsfStorageFileNode.load(child._id), None)
Exemplo n.º 4
0
    def test_delete_file_guids(self):
        child = self.node_settings.get_root().append_file('Test')
        guid = child.get_guid(create=True)

        assert_is_not(OsfStorageFileNode.load(child._id).guids.first(), None)

        with mock.patch('osf.models.files.apps.get_model') as get_model:
            child.delete()

            assert_is(get_model.called, True)
            assert_is(get_model('osf.Comment').objects.filter.called, True)

        assert_is(OsfStorageFileNode.load(child._id), None)
Exemplo n.º 5
0
 def test_get_file_guids_trashed_file_wo_guid(self):
     node = self.node_settings.owner
     file = OsfStorageFile(name='foo', node=node)
     file.save()
     file.delete()
     assert [] == OsfStorageFileNode.get_file_guids(
         '/' + file._id, provider='osfstorage', node=node)
Exemplo n.º 6
0
    def test_delete_file(self):
        child = self.node_settings.get_root().append_file('Test')
        field_names = [
            f.name for f in child._meta.get_fields()
            if not f.is_relation and f.name not in ['id', 'content_type_pk']
        ]
        child_data = {f: getattr(child, f) for f in field_names}
        child.delete()

        assert_is(OsfStorageFileNode.load(child._id), None)
        trashed = models.TrashedFileNode.load(child._id)
        child_storage = dict()
        trashed_storage = dict()
        trashed_storage['parent'] = trashed.parent._id
        child_storage['materialized_path'] = child.materialized_path
        assert_equal(trashed.path, '/' + child._id)
        trashed_field_names = [
            f.name for f in child._meta.get_fields()
            if not f.is_relation and f.name not in [
                'id', '_materialized_path', 'content_type_pk', '_path',
                'deleted_on', 'deleted_by', 'type', 'modified'
            ]
        ]
        for f, value in child_data.iteritems():
            if f in trashed_field_names:
                assert_equal(getattr(trashed, f), value)
Exemplo n.º 7
0
 def test_get_file_guids_live_file_wo_guid(self):
     node = self.node_settings.owner
     file = OsfStorageFile(name='foo', target=node)
     file.save()
     assert [] == OsfStorageFileNode.get_file_guids('/' + file._id,
                                                    provider='osfstorage',
                                                    target=node)
Exemplo n.º 8
0
def checkin_files_by_user(node, user):
    ''' Listens to a contributor being removed to check in all of their files
    '''
    from addons.osfstorage.models import OsfStorageFileNode
    files = OsfStorageFileNode.find(Q('node', 'eq', node) & Q('checkout', 'eq', user))
    for file in files:
        file.checkout = None
        file.save()
Exemplo n.º 9
0
    def setUp(self):
        super(TestPreregFiles, self).setUp()
        self.prereg_user = AuthUserFactory()
        self.user = AuthUserFactory()
        self.node = ProjectFactory(creator=self.user)

        ensure_schemas()
        prereg_schema = get_prereg_schema()
        self.d_of_qs = {
            'q7': OsfStorageFileNode(node=self.node, name='7'),
            'q11': OsfStorageFileNode(node=self.node, name='11'),
            'q16': OsfStorageFileNode(node=self.node, name='16'),
            'q12': OsfStorageFileNode(node=self.node, name='12'),
            'q13': OsfStorageFileNode(node=self.node, name='13'),
            'q19': OsfStorageFileNode(node=self.node, name='19'),
            'q26': OsfStorageFileNode(node=self.node, name='26')
        }
        data = {}
        for q, f in self.d_of_qs.iteritems():
            guid = f.get_guid(create=True)._id
            f.save()
            if q == 'q26':
                data[q] = {
                    'comments': [],
                    'value': '26',
                    'extra': [
                        {
                            'data': {
                                'provider': 'osfstorage',
                                'path': f.path,
                            },
                            'fileId': guid,
                            'nodeId': self.node._id,
                        }
                    ]
                }
                continue
            data[q] = {
                'value': {
                    'uploader': {
                        'extra': [
                            {
                                'data': {
                                    'provider': 'osfstorage',
                                    'path': f.path,
                                },
                                'fileId': guid,
                                'nodeId': self.node._id,
                            }
                        ]
                    }
                }
            }
        self.draft = DraftRegistrationFactory(
            initiator=self.user,
            registration_schema=prereg_schema,
            registration_metadata=data
        )
        self.prereg_user.save()
        self.admin_user = UserFactory()
Exemplo n.º 10
0
def checkin_files_by_user(node, user):
    ''' Listens to a contributor being removed to check in all of their files
    '''
    from addons.osfstorage.models import OsfStorageFileNode
    files = OsfStorageFileNode.find(
        Q('node', 'eq', node) & Q('checkout', 'eq', user))
    for file in files:
        file.checkout = None
        file.save()
Exemplo n.º 11
0
    def test_delete_folder(self):
        parent = self.node_settings.get_root().append_folder('Test')
        kids = []
        for x in range(10):
            kid = parent.append_file(str(x))
            kid.save()
            kids.append(kid)
        count = OsfStorageFileNode.objects.count()
        tcount = models.TrashedFileNode.objects.count()

        parent.delete()

        assert_is(OsfStorageFileNode.load(parent._id), None)
        assert_equals(count - 11, OsfStorageFileNode.objects.count())
        assert_equals(tcount + 11, models.TrashedFileNode.objects.count())

        for kid in kids:
            assert_is(OsfStorageFileNode.load(kid._id), None)
Exemplo n.º 12
0
    def test_get_file_guids_for_live_file(self):
        node = self.node_settings.owner
        file = OsfStorageFile(name='foo', node=node)
        file.save()

        file.get_guid(create=True)
        guid = file.get_guid()._id

        assert guid is not None
        assert guid in OsfStorageFileNode.get_file_guids(
            '/' + file._id, provider='osfstorage', node=node)
Exemplo n.º 13
0
    def test_get_file_guids_for_live_file(self):
        node = self.node_settings.owner
        file = OsfStorageFile(name='foo', target=node)
        file.save()

        file.get_guid(create=True)
        guid = file.get_guid()._id

        assert guid is not None
        assert guid in OsfStorageFileNode.get_file_guids(
            '/' + file._id, provider='osfstorage', target=node)
Exemplo n.º 14
0
    def test_get_file_guids_for_live_folder_wo_guids(self):
        node = self.node_settings.owner
        folder = OsfStorageFolder(name='foofolder', node=node)
        folder.save()

        files = []
        for i in range(1, 4):
            files.append(folder.append_file('foo.{}'.format(i)))

        all_guids = OsfStorageFileNode.get_file_guids(
            '/' + folder._id, provider='osfstorage', node=node)
        assert [] == all_guids
Exemplo n.º 15
0
    def test_delete(self):
        file = self.root_node.append_file('Newfile')

        resp = self.delete(file)

        assert_equal(resp.status_code, 200)
        assert_equal(resp.json, {'status': 'success'})
        fid = file._id
        del file
        # models.StoredFileNode._clear_object_cache()
        assert_is(OsfStorageFileNode.load(fid), None)
        assert_true(models.TrashedFileNode.load(fid))
Exemplo n.º 16
0
    def test_get_file_guids_for_live_folder_wo_guids(self):
        node = self.node_settings.owner
        folder = OsfStorageFolder(name='foofolder', target=node)
        folder.save()

        files = []
        for i in range(1, 4):
            files.append(folder.append_file('foo.{}'.format(i)))

        all_guids = OsfStorageFileNode.get_file_guids(
            '/' + folder._id, provider='osfstorage', target=node)
        assert [] == all_guids
Exemplo n.º 17
0
    def test_delete(self):
        file = self.root_node.append_file('Newfile')

        resp = self.delete(file)

        assert_equal(resp.status_code, 200)
        assert_equal(resp.json, {'status': 'success'})
        fid = file._id
        del file
        # models.StoredFileNode._clear_object_cache()
        assert_is(OsfStorageFileNode.load(fid), None)
        assert_true(models.TrashedFileNode.load(fid))
Exemplo n.º 18
0
    def test_delete_folder(self):
        parent = self.node_settings.get_root().append_folder('Test')
        kids = []
        for x in range(10):
            kid = parent.append_file(str(x))
            kid.save()
            kids.append(kid)
        count = OsfStorageFileNode.find().count()
        tcount = models.TrashedFileNode.find().count()

        parent.delete()

        assert_is(OsfStorageFileNode.load(parent._id), None)
        assert_equals(count - 11, OsfStorageFileNode.find().count())
        assert_equals(tcount + 11, models.TrashedFileNode.find().count())

        for kid in kids:
            assert_is(
                OsfStorageFileNode.load(kid._id),
                None
            )
Exemplo n.º 19
0
        def wrapped(*args, **kwargs):
            if 'fid' not in kwargs and default_root:
                file_node = OsfStorageFolder.objects.get_root(kwargs['target'])
            else:
                file_node = OsfStorageFileNode.get(kwargs.get('fid'), kwargs['target'])
            if must_be and file_node.kind != must_be:
                raise HTTPError(httplib.BAD_REQUEST, data={
                    'message_short': 'incorrect type',
                    'message_long': 'FileNode must be of type {} not {}'.format(must_be, file_node.kind)
                })

            kwargs['file_node'] = file_node

            return func(*args, **kwargs)
Exemplo n.º 20
0
    def test_create_with_parent(self):
        resp = self.create_folder('name')

        assert_equal(resp.status_code, 201)
        assert_equal(self.root_node.children.count(), 1)
        assert_equal(self.root_node.children.all()[0].serialize(), resp.json['data'])

        resp = self.create_folder('name', parent=OsfStorageFileNode.load(resp.json['data']['id']))

        assert_equal(resp.status_code, 201)
        assert_equal(self.root_node.children.count(), 1)
        assert_false(self.root_node.children.all()[0].is_file)
        assert_equal(self.root_node.children.all()[0].children.count(), 1)
        assert_false(self.root_node.children.all()[0].children.all()[0].is_file)
        assert_equal(self.root_node.children.all()[0].children.all()[0].serialize(), resp.json['data'])
Exemplo n.º 21
0
    def test_create_with_parent(self):
        resp = self.create_folder('name')

        assert_equal(resp.status_code, 201)
        assert_equal(self.root_node.children.count(), 1)
        assert_equal(self.root_node.children.all()[0].serialize(), resp.json['data'])

        resp = self.create_folder('name', parent=OsfStorageFileNode.load(resp.json['data']['id']))

        assert_equal(resp.status_code, 201)
        assert_equal(self.root_node.children.count(), 1)
        assert_false(self.root_node.children.all()[0].is_file)
        assert_equal(self.root_node.children.all()[0].children.count(), 1)
        assert_false(self.root_node.children.all()[0].children.all()[0].is_file)
        assert_equal(self.root_node.children.all()[0].children.all()[0].serialize(), resp.json['data'])
Exemplo n.º 22
0
    def test_get_file_guids_for_live_folder(self):
        node = self.node_settings.owner
        folder = OsfStorageFolder(name='foofolder', target=node)
        folder.save()

        files = []
        for i in range(1, 4):
            files.append(folder.append_file('foo.{}'.format(i)))
            files[-1].get_guid(create=True)

        guids = [file.get_guid()._id for file in files]
        assert len(guids) == len(files)

        all_guids = OsfStorageFileNode.get_file_guids(
            '/' + folder._id, provider='osfstorage', target=node)
        assert sorted(guids) == sorted(all_guids)
Exemplo n.º 23
0
    def test_get_file_guids_for_live_folder(self):
        node = self.node_settings.owner
        folder = OsfStorageFolder(name='foofolder', node=node)
        folder.save()

        files = []
        for i in range(1, 4):
            files.append(folder.append_file('foo.{}'.format(i)))
            files[-1].get_guid(create=True)

        guids = [file.get_guid()._id for file in files]
        assert len(guids) == len(files)

        all_guids = OsfStorageFileNode.get_file_guids(
            '/' + folder._id, provider='osfstorage', node=node)
        assert sorted(guids) == sorted(all_guids)
Exemplo n.º 24
0
    def wrapped(payload, *args, **kwargs):
        try:
            user = OSFUser.load(payload['user'])
            dest_node = AbstractNode.load(payload['destination']['node'])
            source = OsfStorageFileNode.get(payload['source'], kwargs['node'])
            dest_parent = OsfStorageFolder.get(payload['destination']['parent'], dest_node)

            kwargs.update({
                'user': user,
                'source': source,
                'destination': dest_parent,
                'name': payload['destination']['name'],
            })
        except KeyError:
            raise HTTPError(httplib.BAD_REQUEST)

        return func(*args, **kwargs)
Exemplo n.º 25
0
    def test_get_file_guids_for_trashed_folder_recursive_wo_guids(self):
        node = self.node_settings.owner
        folder = OsfStorageFolder(name='foofolder', target=node)
        folder.save()

        files = []
        for i in range(1, 4):
            files.append(folder.append_file('foo.{}'.format(i)))

        subfolder = folder.append_folder('subfoo')
        for i in range(1, 4):
            files.append(subfolder.append_file('subfoo.{}'.format(i)))

        folder.delete()

        all_guids = OsfStorageFileNode.get_file_guids(
            '/' + folder._id, provider='osfstorage', target=node)
        assert [] == all_guids
Exemplo n.º 26
0
    def test_delete_file(self):
        child = self.node_settings.get_root().append_file('Test')
        field_names = [f.name for f in child._meta.get_fields() if not f.is_relation and f.name not in ['id', 'content_type_pk']]
        child_data = {f: getattr(child, f) for f in field_names}
        child.delete()

        assert_is(OsfStorageFileNode.load(child._id), None)
        trashed = models.TrashedFileNode.load(child._id)
        child_storage = dict()
        trashed_storage = dict()
        trashed_storage['parent'] = trashed.parent._id
        child_storage['materialized_path'] = child.materialized_path
        assert_equal(trashed.path, '/' + child._id)
        trashed_field_names = [f.name for f in child._meta.get_fields() if not f.is_relation and
                               f.name not in ['id', '_materialized_path', 'content_type_pk', '_path', 'deleted_on', 'deleted_by', 'type']]
        for f, value in child_data.iteritems():
            if f in trashed_field_names:
                assert_equal(getattr(trashed, f), value)
Exemplo n.º 27
0
    def test_get_file_guids_for_trashed_folder_recursive_wo_guids(self):
        node = self.node_settings.owner
        folder = OsfStorageFolder(name='foofolder', node=node)
        folder.save()

        files = []
        for i in range(1, 4):
            files.append(folder.append_file('foo.{}'.format(i)))

        subfolder = folder.append_folder('subfoo')
        for i in range(1, 4):
            files.append(subfolder.append_file('subfoo.{}'.format(i)))

        folder.delete()

        all_guids = OsfStorageFileNode.get_file_guids(
            '/' + folder._id, provider='osfstorage', node=node)
        assert [] == all_guids
Exemplo n.º 28
0
    def wrapped(payload, *args, **kwargs):
        try:
            user = OSFUser.load(payload['user'])
            dest_node = AbstractNode.load(payload['destination']['node'])
            source = OsfStorageFileNode.get(payload['source'], kwargs['node'])
            dest_parent = OsfStorageFolder.get(
                payload['destination']['parent'], dest_node)

            kwargs.update({
                'user': user,
                'source': source,
                'destination': dest_parent,
                'name': payload['destination']['name'],
            })
        except KeyError:
            raise HTTPError(httplib.BAD_REQUEST)

        return func(*args, **kwargs)
Exemplo n.º 29
0
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(data=request.data, context=self.get_serializer_context())
        if serializer.is_valid():
            source = serializer.validated_data.pop('source')
            destination = serializer.validated_data.pop('destination')
            name = destination.get('name')
            dest_target = self.get_target(target_id=destination.get('target'))
            try:
                source = OsfStorageFileNode.get(source, self.get_object())
            except OsfStorageFileNode.DoesNotExist:
                raise NotFound

            try:
                dest_parent = OsfStorageFolder.get(destination.get('parent'), dest_target)
            except OsfStorageFolder.DoesNotExist:
                raise NotFound
            serializer.save(source=source, destination=dest_parent, name=name)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Exemplo n.º 30
0
    def wrapped(payload, *args, **kwargs):
        try:
            user = OSFUser.load(payload['user'])
            # Waterbutler is sending back ['node'] under the destination payload - WB should change to target
            target = payload['destination'].get('target') or payload['destination'].get('node')
            dest_target = Guid.load(target).referent
            source = OsfStorageFileNode.get(payload['source'], kwargs['target'])
            dest_parent = OsfStorageFolder.get(payload['destination']['parent'], dest_target)

            kwargs.update({
                'user': user,
                'source': source,
                'destination': dest_parent,
                'name': payload['destination']['name'],
            })
        except KeyError:
            raise HTTPError(httplib.BAD_REQUEST)

        return func(*args, **kwargs)
Exemplo n.º 31
0
        def wrapped(*args, **kwargs):
            if 'fid' not in kwargs and default_root:
                file_node = OsfStorageFolder.objects.get_root(kwargs['target'])
            else:
                file_node = OsfStorageFileNode.get(kwargs.get('fid'),
                                                   kwargs['target'])
            if must_be and file_node.kind != must_be:
                raise HTTPError(
                    httplib.BAD_REQUEST,
                    data={
                        'message_short':
                        'incorrect type',
                        'message_long':
                        'FileNode must be of type {} not {}'.format(
                            must_be, file_node.kind)
                    })

            kwargs['file_node'] = file_node

            return func(*args, **kwargs)
Exemplo n.º 32
0
    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(
            data=request.data, context=self.get_serializer_context())
        if serializer.is_valid():
            source = serializer.validated_data.pop('source')
            destination = serializer.validated_data.pop('destination')
            name = destination.get('name')
            dest_target = self.get_target(target_id=destination.get('target'))
            try:
                source = OsfStorageFileNode.get(source, self.get_object())
            except OsfStorageFileNode.DoesNotExist:
                raise NotFound

            try:
                dest_parent = OsfStorageFolder.get(destination.get('parent'),
                                                   dest_target)
            except OsfStorageFolder.DoesNotExist:
                raise NotFound
            serializer.save(source=source, destination=dest_parent, name=name)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Exemplo n.º 33
0
def welcome_osf4m(email):
    """ presend has two functions. First is to make sure that the user has not
    converted to a regular OSF user by logging in. Second is to populate the
    data field with downloads by finding the file/project (node_settings) and
    counting downloads of all files within that project

    :param email: QueuedMail object with data field including fid
    :return: boolean based on whether the email should be sent
    """
    # In line import to prevent circular importing
    from addons.osfstorage.models import OsfStorageFileNode
    if email.user.date_last_login:
        if email.user.date_last_login > timezone.now() - settings.WELCOME_OSF4M_WAIT_TIME_GRACE:
            return False
    upload = OsfStorageFileNode.load(email.data['fid'])
    if upload:
        email.data['downloads'] = upload.get_download_count()
    else:
        email.data['downloads'] = 0
    email.save()
    return True
Exemplo n.º 34
0
def welcome_osf4m(email):
    """ presend has two functions. First is to make sure that the user has not
    converted to a regular OSF user by logging in. Second is to populate the
    data field with downloads by finding the file/project (node_settings) and
    counting downloads of all files within that project

    :param email: QueuedMail object with data field including fid
    :return: boolean based on whether the email should be sent
    """
    # In line import to prevent circular importing
    from addons.osfstorage.models import OsfStorageFileNode
    if email.user.date_last_login:
        if email.user.date_last_login > timezone.now() - settings.WELCOME_OSF4M_WAIT_TIME_GRACE:
            return False
    upload = OsfStorageFileNode.load(email.data['fid'])
    if upload:
        email.data['downloads'] = upload.get_download_count()
    else:
        email.data['downloads'] = 0
    email.save()
    return True
Exemplo n.º 35
0
    def wrapped(payload, *args, **kwargs):
        try:
            user = OSFUser.load(payload['user'])
            # Waterbutler is sending back ['node'] under the destination payload - WB should change to target
            target = payload['destination'].get(
                'target') or payload['destination'].get('node')
            dest_target = Guid.load(target).referent
            source = OsfStorageFileNode.get(payload['source'],
                                            kwargs['target'])
            dest_parent = OsfStorageFolder.get(
                payload['destination']['parent'], dest_target)

            kwargs.update({
                'user': user,
                'source': source,
                'destination': dest_parent,
                'name': payload['destination']['name'],
            })
        except KeyError:
            raise HTTPError(httplib.BAD_REQUEST)

        return func(*args, **kwargs)
Exemplo n.º 36
0
def get_auth(auth, **kwargs):
    cas_resp = None
    if not auth.user:
        # Central Authentication Server OAuth Bearer Token
        authorization = request.headers.get('Authorization')
        if authorization and authorization.startswith('Bearer '):
            client = cas.get_client()
            try:
                access_token = cas.parse_auth_header(authorization)
                cas_resp = client.profile(access_token)
            except cas.CasError as err:
                sentry.log_exception()
                # NOTE: We assume that the request is an AJAX request
                return json_renderer(err)
            if cas_resp.authenticated:
                auth.user = OSFUser.load(cas_resp.user)

    try:
        data = jwt.decode(jwe.decrypt(
            request.args.get('payload', '').encode('utf-8'),
            WATERBUTLER_JWE_KEY),
                          settings.WATERBUTLER_JWT_SECRET,
                          options={'require_exp': True},
                          algorithm=settings.WATERBUTLER_JWT_ALGORITHM)['data']
    except (jwt.InvalidTokenError, KeyError) as err:
        sentry.log_message(str(err))
        raise HTTPError(http_status.HTTP_403_FORBIDDEN)

    if not auth.user:
        auth.user = OSFUser.from_cookie(data.get('cookie', ''))

    try:
        action = data['action']
        node_id = data['nid']
        provider_name = data['provider']
    except KeyError:
        raise HTTPError(http_status.HTTP_400_BAD_REQUEST)

    node = AbstractNode.load(node_id) or Preprint.load(node_id)
    if node and node.is_deleted:
        raise HTTPError(http_status.HTTP_410_GONE)
    elif not node:
        raise HTTPError(http_status.HTTP_404_NOT_FOUND)

    check_access(node, auth, action, cas_resp)
    provider_settings = None
    if hasattr(node, 'get_addon'):
        provider_settings = node.get_addon(provider_name)
        if not provider_settings:
            raise HTTPError(http_status.HTTP_400_BAD_REQUEST)

    path = data.get('path')
    credentials = None
    waterbutler_settings = None
    fileversion = None
    if provider_name == 'osfstorage':
        if path:
            file_id = path.strip('/')
            # check to see if this is a file or a folder
            filenode = OsfStorageFileNode.load(path.strip('/'))
            if filenode and filenode.is_file:
                # default to most recent version if none is provided in the response
                version = int(data['version']) if data.get(
                    'version') else filenode.versions.count()
                try:
                    fileversion = FileVersion.objects.filter(
                        basefilenode___id=file_id,
                        identifier=version).select_related('region').get()
                except FileVersion.DoesNotExist:
                    raise HTTPError(http_status.HTTP_400_BAD_REQUEST)
                if auth.user:
                    # mark fileversion as seen
                    FileVersionUserMetadata.objects.get_or_create(
                        user=auth.user, file_version=fileversion)
                if not node.is_contributor_or_group_member(auth.user):
                    from_mfr = download_is_from_mfr(request, payload=data)
                    # version index is 0 based
                    version_index = version - 1
                    if action == 'render':
                        update_analytics(node, filenode, version_index, 'view')
                    elif action == 'download' and not from_mfr:
                        update_analytics(node, filenode, version_index,
                                         'download')
                    if waffle.switch_is_active(features.ELASTICSEARCH_METRICS):
                        if isinstance(node, Preprint):
                            metric_class = get_metric_class_for_action(
                                action, from_mfr=from_mfr)
                            if metric_class:
                                sloan_flags = {
                                    'sloan_id':
                                    request.cookies.get(SLOAN_ID_COOKIE_NAME)
                                }
                                for flag_name in SLOAN_FLAGS:
                                    value = request.cookies.get(
                                        f'dwf_{flag_name}_custom_domain'
                                    ) or request.cookies.get(
                                        f'dwf_{flag_name}')
                                    if value:
                                        sloan_flags[flag_name.replace(
                                            '_display', '')] = strtobool(value)

                                try:
                                    metric_class.record_for_preprint(
                                        preprint=node,
                                        user=auth.user,
                                        version=fileversion.identifier
                                        if fileversion else None,
                                        path=path,
                                        **sloan_flags)
                                except es_exceptions.ConnectionError:
                                    log_exception()
        if fileversion and provider_settings:
            region = fileversion.region
            credentials = region.waterbutler_credentials
            waterbutler_settings = fileversion.serialize_waterbutler_settings(
                node_id=provider_settings.owner._id,
                root_id=provider_settings.root_node._id,
            )
    # If they haven't been set by version region, use the NodeSettings or Preprint directly
    if not (credentials and waterbutler_settings):
        credentials = node.serialize_waterbutler_credentials(provider_name)
        waterbutler_settings = node.serialize_waterbutler_settings(
            provider_name)

    if isinstance(credentials.get('token'), bytes):
        credentials['token'] = credentials.get('token').decode()

    return {
        'payload':
        jwe.encrypt(
            jwt.encode(
                {
                    'exp':
                    timezone.now() + datetime.timedelta(
                        seconds=settings.WATERBUTLER_JWT_EXPIRATION),
                    'data': {
                        'auth':
                        make_auth(
                            auth.user
                        ),  # A waterbutler auth dict not an Auth object
                        'credentials':
                        credentials,
                        'settings':
                        waterbutler_settings,
                        'callback_url':
                        node.api_url_for(
                            ('create_waterbutler_log'
                             if not getattr(node, 'is_registration', False)
                             else 'registration_callbacks'),
                            _absolute=True,
                            _internal=True)
                    }
                },
                settings.WATERBUTLER_JWT_SECRET,
                algorithm=settings.WATERBUTLER_JWT_ALGORITHM),
            WATERBUTLER_JWE_KEY).decode()
    }
Exemplo n.º 37
0
def get_auth(auth, **kwargs):
    cas_resp = None
    if not auth.user:
        # Central Authentication Server OAuth Bearer Token
        authorization = request.headers.get('Authorization')
        if authorization and authorization.startswith('Bearer '):
            client = cas.get_client()
            try:
                access_token = cas.parse_auth_header(authorization)
                cas_resp = client.profile(access_token)
            except cas.CasError as err:
                sentry.log_exception()
                # NOTE: We assume that the request is an AJAX request
                return json_renderer(err)
            if cas_resp.authenticated:
                auth.user = OSFUser.load(cas_resp.user)

    try:
        data = jwt.decode(
            jwe.decrypt(request.args.get('payload', '').encode('utf-8'), WATERBUTLER_JWE_KEY),
            settings.WATERBUTLER_JWT_SECRET,
            options={'require_exp': True},
            algorithm=settings.WATERBUTLER_JWT_ALGORITHM
        )['data']
    except (jwt.InvalidTokenError, KeyError) as err:
        sentry.log_message(str(err))
        raise HTTPError(httplib.FORBIDDEN)

    if not auth.user:
        auth.user = OSFUser.from_cookie(data.get('cookie', ''))

    try:
        action = data['action']
        node_id = data['nid']
        provider_name = data['provider']
    except KeyError:
        raise HTTPError(httplib.BAD_REQUEST)

    node = AbstractNode.load(node_id) or Preprint.load(node_id)
    if not node:
        raise HTTPError(httplib.NOT_FOUND)

    check_access(node, auth, action, cas_resp)
    provider_settings = None
    if hasattr(node, 'get_addon'):
        provider_settings = node.get_addon(provider_name)
        if not provider_settings:
            raise HTTPError(httplib.BAD_REQUEST)

    try:
        path = data.get('path')
        version = data.get('version')
        credentials = None
        waterbutler_settings = None
        fileversion = None
        if provider_name == 'osfstorage':
            if path and version:
                # check to see if this is a file or a folder
                filenode = OsfStorageFileNode.load(path.strip('/'))
                if filenode and filenode.is_file:
                    try:
                        fileversion = FileVersion.objects.filter(
                            basefilenode___id=path.strip('/'),
                            identifier=version
                        ).select_related('region').get()
                    except FileVersion.DoesNotExist:
                        raise HTTPError(httplib.BAD_REQUEST)
            # path and no version, use most recent version
            elif path:
                filenode = OsfStorageFileNode.load(path.strip('/'))
                if filenode and filenode.is_file:
                    fileversion = FileVersion.objects.filter(
                        basefilenode=filenode
                    ).select_related('region').order_by('-created').first()
            if fileversion:
                region = fileversion.region
                credentials = region.waterbutler_credentials
                waterbutler_settings = fileversion.serialize_waterbutler_settings(
                    node_id=provider_settings.owner._id if provider_settings else node._id,
                    root_id=provider_settings.root_node._id if provider_settings else node.root_folder._id,
                )
        # If they haven't been set by version region, use the NodeSettings region
        if not (credentials and waterbutler_settings):
            credentials = node.serialize_waterbutler_credentials(provider_name)
            waterbutler_settings = node.serialize_waterbutler_settings(provider_name)
    except exceptions.AddonError:
        log_exception()
        raise HTTPError(httplib.BAD_REQUEST)

    # TODO: Add a signal here?
    if waffle.switch_is_active(features.ELASTICSEARCH_METRICS):
        user = auth.user
        if isinstance(node, Preprint) and not node.is_contributor(user):
            metric_class = get_metric_class_for_action(action)
            if metric_class:
                try:
                    metric_class.record_for_preprint(
                        preprint=node,
                        user=user,
                        version=fileversion.identifier if fileversion else None,
                        path=path
                    )
                except es_exceptions.ConnectionError:
                    log_exception()

    return {'payload': jwe.encrypt(jwt.encode({
        'exp': timezone.now() + datetime.timedelta(seconds=settings.WATERBUTLER_JWT_EXPIRATION),
        'data': {
            'auth': make_auth(auth.user),  # A waterbutler auth dict not an Auth object
            'credentials': credentials,
            'settings': waterbutler_settings,
            'callback_url': node.api_url_for(
                ('create_waterbutler_log' if not getattr(node, 'is_registration', False) else 'registration_callbacks'),
                _absolute=True,
                _internal=True
            )
        }
    }, settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM), WATERBUTLER_JWE_KEY)}