Skip to content

Commit

Permalink
Merge 74023f2 into 5ae01a4
Browse files Browse the repository at this point in the history
  • Loading branch information
alexschiller committed Dec 2, 2017
2 parents 5ae01a4 + 74023f2 commit 318540c
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 117 deletions.
33 changes: 22 additions & 11 deletions addons/base/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from website import settings
from addons.base import logger, serializer
from website.oauth.signals import oauth_complete
from website.util import waterbutler_url_for
from website.util import waterbutler_api_url_for

lookup = TemplateLookup(
directories=[
Expand Down Expand Up @@ -561,26 +561,37 @@ def archive_folder_name(self):
return name

def _get_fileobj_child_metadata(self, filenode, user, cookie=None, version=None):
kwargs = dict(
provider=self.config.short_name,
path=filenode.get('path', ''),
node=self.owner,

kwargs = {}
if version:
kwargs['version'] = version
if cookie:
kwargs['cookie'] = cookie
elif user:
kwargs['cookie'] = user.get_or_create_cookie()

metadata_url = waterbutler_api_url_for(
self.owner._id,
self.config.short_name,
path=filenode.get('path', '/'),
user=user,
view_only=True,
_internal=True,
**kwargs
)
if cookie:
kwargs['cookie'] = cookie
if version:
kwargs['version'] = version
metadata_url = waterbutler_url_for('metadata', _internal=True, **kwargs)

res = requests.get(metadata_url)

if res.status_code != 200:
raise HTTPError(res.status_code, data={'error': res.json()})

# TODO: better throttling?
time.sleep(1.0 / 5.0)
return res.json().get('data', [])

data = res.json().get('data', None)
if data:
return [child['attributes'] for child in data]
return []

def _get_file_tree(self, filenode=None, user=None, cookie=None, version=None):
"""
Expand Down
14 changes: 13 additions & 1 deletion api/base/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import urllib
import urlparse

import furl
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import OuterRef, Exists, Q
from rest_framework.exceptions import NotFound
Expand Down Expand Up @@ -124,6 +123,18 @@ def get_object_or_error(model_cls, query_or_pk, request, display_name=None):
return obj


<<<<<<< HEAD
def default_node_list_queryset():
return Node.objects.filter(is_deleted=False)

def default_node_permission_queryset(user):
if user.is_anonymous:
return Node.objects.filter(is_public=True)
return Node.objects.filter(Q(is_public=True) | Q(contributor__user_id=user.pk))

def default_registration_list_queryset():
return Registration.objects.filter(is_deleted=False)
=======
def waterbutler_url_for(request_type, provider, path, node_id, token, obj_args=None, **query):
"""Reverse URL lookup for WaterButler routes
:param str request_type: data or metadata
Expand Down Expand Up @@ -154,6 +165,7 @@ def waterbutler_url_for(request_type, provider, path, node_id, token, obj_args=N
def default_node_list_queryset(model_cls):
assert model_cls in {Node, Registration}
return model_cls.objects.filter(is_deleted=False)
>>>>>>> 5ae01a4878c9326e7ec9f9b2c3834f8db3276ee1

def default_node_permission_queryset(user, model_cls):
assert model_cls in {Node, Registration}
Expand Down
89 changes: 69 additions & 20 deletions osf_tests/test_archiver.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

from website import mails
from website import settings
from website.util import waterbutler_url_for
from website.util import waterbutler_api_url_for
from website.util.sanitize import strip_html
from osf.models import MetaSchema
from addons.base.models import BaseStorageAddon
Expand Down Expand Up @@ -147,6 +147,42 @@ def select_files_from_tree(file_tree):
],
}

WB_FILE_TREE = {
'attributes': {
'path': '/',
'name': '',
'kind': 'folder',
'children': [
{
'attributes': {
'path': '/1234567',
'name': 'Afile.file',
'kind': 'file',
'size': '128',
}
},
{
'attributes': {
'path': '/qwerty',
'name': 'A Folder',
'kind': 'folder',
'children': [
{
'attributes': {
'path': '/qwerty/asdfgh',
'name': 'coolphoto.png',
'kind': 'file',
'size': '256',
}
}
],
}
}
],
}
}


class MockAddon(object):

complete = True
Expand Down Expand Up @@ -357,28 +393,36 @@ def setUp(self):
self.archive_job = self.dst.archive_job

class TestStorageAddonBase(ArchiverTestCase):

RESP_MAP = {
'/': dict(data=FILE_TREE['children']),
'/1234567': dict(data=FILE_TREE['children'][0]),
'/qwerty': dict(data=FILE_TREE['children'][1]['children']),
'/qwerty/asdfgh': dict(data=FILE_TREE['children'][1]['children'][0]),
}

tree_root = WB_FILE_TREE['attributes']['children']
tree_child = tree_root[0]
tree_grandchild = tree_root[1]['attributes']['children']
tree_great_grandchild = tree_grandchild[0]

URLS = ['/', '/1234567', '/qwerty', '/qwerty/asdfgh']

def get_resp(self, url):
if '/qwerty/asdfgh' in url:
return dict(data=self.tree_great_grandchild)
if '/qwerty' in url:
return dict(data=self.tree_grandchild)
if '/1234567' in url:
return dict(data=self.tree_child)
return dict(data=self.tree_root)

@httpretty.activate
def _test__get_file_tree(self, addon_short_name):
requests_made = []
# requests_to_make = []
def callback(request, uri, headers):
path = request.querystring['path'][0]
requests_made.append(path)
return (200, headers, json.dumps(self.RESP_MAP[path]))

for path in self.RESP_MAP.keys():
url = waterbutler_url_for(
'metadata',
provider=addon_short_name,
requests_made.append(uri)
return (200, headers, json.dumps(self.get_resp(uri)))

for path in self.URLS:
url = waterbutler_api_url_for(
self.src._id,
addon_short_name,
meta=True,
path=path,
node=self.src,
user=self.user,
view_only=True,
_internal=True,
Expand All @@ -395,12 +439,17 @@ def callback(request, uri, headers):
}
file_tree = addon._get_file_tree(root, self.user)
assert_equal(FILE_TREE, file_tree)
assert_equal(requests_made, ['/', '/qwerty']) # no requests made for files
assert_equal(len(requests_made), 2)

# Makes a request for folders ('/qwerty') but not files ('/1234567', '/qwerty/asdfgh')
assert_true(any('/qwerty' in url for url in requests_made))
assert_false(any('/1234567' in url for url in requests_made))
assert_false(any('/qwerty/asdfgh' in url for url in requests_made))

def _test_addon(self, addon_short_name):
self._test__get_file_tree(addon_short_name)

@pytest.mark.skip('Unskip when figshare addon is implemented')
# @pytest.mark.skip('Unskip when figshare addon is implemented')
def test_addons(self):
# Test that each addon in settings.ADDONS_ARCHIVABLE other than wiki/forward implements the StorageAddonBase interface
for addon in [a for a in settings.ADDONS_ARCHIVABLE if a not in ['wiki', 'forward']]:
Expand Down
21 changes: 10 additions & 11 deletions tests/test_conferences.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,40 +188,39 @@ def test_provision_spam(self):
assert_in('emailed', self.node.system_tags)
assert_in('spam', self.node.system_tags)

@mock.patch('website.util.waterbutler_url_for')
@mock.patch('website.util.waterbutler_api_url_for')
@mock.patch('website.conferences.utils.requests.put')
def test_upload(self, mock_put, mock_get_url):
mock_get_url.return_value = 'http://queen.com/'
self.attachment.filename = 'hammer-to-fall'
file_name = 'hammer-to-fall'
self.attachment.filename = file_name
self.attachment.content_type = 'application/json'
utils.upload_attachment(self.user, self.node, self.attachment)
mock_get_url.assert_called_with(
'upload',
self.node._id,
'osfstorage',
'/' + self.attachment.filename,
self.node,
_internal=True,
user=self.user,
cookie=self.user.get_or_create_cookie(),
name='/' + file_name
)
mock_put.assert_called_with(
mock_get_url.return_value,
data=self.content,
)

@mock.patch('website.util.waterbutler_url_for')
@mock.patch('website.util.waterbutler_api_url_for')
@mock.patch('website.conferences.utils.requests.put')
def test_upload_no_file_name(self, mock_put, mock_get_url):
mock_get_url.return_value = 'http://queen.com/'
self.attachment.filename = ''
self.attachment.content_type = 'application/json'
utils.upload_attachment(self.user, self.node, self.attachment)
mock_get_url.assert_called_with(
'upload',
self.node._id,
'osfstorage',
'/' + settings.MISSING_FILE_NAME,
self.node,
_internal=True,
user=self.user,
cookie=self.user.get_or_create_cookie(),
name='/' + settings.MISSING_FILE_NAME,
)
mock_put.assert_called_with(
mock_get_url.return_value,
Expand Down
49 changes: 12 additions & 37 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from website import util
from website.util import paths
from website.util.mimetype import get_mimetype
from website.util import web_url_for, api_url_for, is_json_request, waterbutler_url_for, conjunct, api_v2_url
from website.util import web_url_for, api_url_for, is_json_request, waterbutler_api_url_for, conjunct, api_v2_url
from website.project import utils as project_utils
from website.profile import utils as profile_utils
from website.util.time import throttle_period_expired
Expand Down Expand Up @@ -56,7 +56,6 @@ def test_throttle_period_expired_using_timestamp_in_seconds(self):
is_expired = throttle_period_expired(timestamp=(timestamp - 31), throttle=30)
assert_true(is_expired)


class TestUrlForHelpers(unittest.TestCase):

def setUp(self):
Expand Down Expand Up @@ -205,48 +204,24 @@ def test_is_json_request(self):
with self.app.test_request_context(content_type='application/json;charset=UTF-8'):
assert_true(is_json_request())

def test_waterbutler_url_for(self):
def test_waterbutler_api_url_for(self):
with self.app.test_request_context():
url = waterbutler_url_for('upload', 'provider', 'path', mock.Mock(_id='_id'))

assert_in('nid=_id', url)
assert_in('/file?', url)
assert_in('path=path', url)
assert_in('provider=provider', url)
url = waterbutler_api_url_for('fakeid', 'provider', '/path')
assert_in('/fakeid/', url)
assert_in('/path', url)
assert_in('/providers/provider/', url)
assert_in(settings.WATERBUTLER_URL, url)

def test_waterbutler_url_for_internal(self):
def test_waterbutler_api_url_for_internal(self):
settings.WATERBUTLER_INTERNAL_URL = 'http://1.2.3.4:7777'
with self.app.test_request_context():
url = waterbutler_url_for('upload', 'provider', 'path', mock.Mock(_id='_id'), _internal=True)
url = waterbutler_api_url_for('fakeid', 'provider', '/path', _internal=True)

assert_not_in(settings.WATERBUTLER_URL, url)
assert_in(settings.WATERBUTLER_INTERNAL_URL, url)
assert_in('nid=_id', url)
assert_in('/file?', url)
assert_in('path=path', url)
assert_in('provider=provider', url)

def test_waterbutler_url_for_implicit_cookie(self):
with self.app.test_request_context() as context:
context.request.cookies = {settings.COOKIE_NAME: 'cookie'}
url = waterbutler_url_for('upload', 'provider', 'path', mock.Mock(_id='_id'))

assert_in('nid=_id', url)
assert_in('/file?', url)
assert_in('path=path', url)
assert_in('cookie=cookie', url)
assert_in('provider=provider', url)

def test_waterbutler_url_for_cookie_not_required(self):
with self.app.test_request_context():
url = waterbutler_url_for('upload', 'provider', 'path', mock.Mock(_id='_id'))

assert_not_in('cookie', url)

assert_in('nid=_id', url)
assert_in('/file?', url)
assert_in('path=path', url)
assert_in('provider=provider', url)
assert_in('/fakeid/', url)
assert_in('/path', url)
assert_in('/providers/provider', url)


class TestGetMimeTypes(unittest.TestCase):
Expand Down
2 changes: 1 addition & 1 deletion website/conferences/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def upload_attachment(user, node, attachment):
attachment.seek(0)
name = '/' + (attachment.filename or settings.MISSING_FILE_NAME)
content = attachment.read()
upload_url = util.waterbutler_url_for('upload', 'osfstorage', name, node, user=user, _internal=True)
upload_url = util.waterbutler_api_url_for(node._id, 'osfstorage', name=name, cookie=user.get_or_create_cookie(), _internal=True)

requests.put(
upload_url,
Expand Down
36 changes: 0 additions & 36 deletions website/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,42 +141,6 @@ def is_json_request():
return content_type and ('application/json' in content_type)


def waterbutler_url_for(route, provider, path, node, user=None, _internal=False, **kwargs):
"""DEPRECATED Use waterbutler_api_url_for
Reverse URL lookup for WaterButler routes
:param str route: The action to preform, upload, download, delete...
:param str provider: The name of the requested provider
:param str path: The path of the requested file or folder
:param Node node: The node being accessed
:param User user: The user whos cookie will be used or None
:param dict kwargs: Addition query parameters to be appended
"""
url = furl.furl(website_settings.WATERBUTLER_INTERNAL_URL if _internal else website_settings.WATERBUTLER_URL)
url.path.segments.append(waterbutler_action_map[route])

url.args.update({
'path': path,
'nid': node._id,
'provider': provider,
})

if user:
url.args['cookie'] = user.get_or_create_cookie()
elif website_settings.COOKIE_NAME in request.cookies:
url.args['cookie'] = request.cookies[website_settings.COOKIE_NAME]

view_only = False
if 'view_only' in kwargs:
view_only = kwargs.get('view_only')
else:
view_only = request.args.get('view_only')

url.args['view_only'] = view_only

url.args.update(kwargs)
return url.url


def waterbutler_api_url_for(node_id, provider, path='/', _internal=False, **kwargs):
assert path.startswith('/'), 'Path must always start with /'
url = furl.furl(website_settings.WATERBUTLER_INTERNAL_URL if _internal else website_settings.WATERBUTLER_URL)
Expand Down

0 comments on commit 318540c

Please sign in to comment.