class TestDropboxNodeSettingsModel(OsfTestCase): def setUp(self): super(TestDropboxNodeSettingsModel, self).setUp() self.user = UserFactory() self.user.add_addon('dropbox') self.user.save() self.user_settings = self.user.get_addon('dropbox') self.project = ProjectFactory() self.node_settings = DropboxNodeSettingsFactory( user_settings=self.user_settings, owner=self.project ) def test_fields(self): node_settings = DropboxNodeSettings(user_settings=self.user_settings) node_settings.save() assert_true(node_settings.user_settings) assert_equal(node_settings.user_settings.owner, self.user) assert_true(hasattr(node_settings, 'folder')) assert_true(hasattr(node_settings, 'registration_data')) def test_folder_defaults_to_none(self): node_settings = DropboxNodeSettings(user_settings=self.user_settings) node_settings.save() assert_is_none(node_settings.folder) def test_has_auth(self): settings = DropboxNodeSettings(user_settings=self.user_settings) settings.save() assert_false(settings.has_auth) settings.user_settings.access_token = '123abc' settings.user_settings.save() assert_true(settings.has_auth) def test_to_json(self): settings = self.node_settings user = UserFactory() result = settings.to_json(user) assert_equal(result['addon_short_name'], 'dropbox') def test_delete(self): assert_true(self.node_settings.user_settings) assert_true(self.node_settings.folder) old_logs = self.project.logs self.node_settings.delete() self.node_settings.save() assert_is(self.node_settings.user_settings, None) assert_is(self.node_settings.folder, None) assert_true(self.node_settings.deleted) assert_equal(self.project.logs, old_logs) def test_deauthorize(self): assert_true(self.node_settings.user_settings) assert_true(self.node_settings.folder) self.node_settings.deauthorize(auth=Auth(self.user)) self.node_settings.save() assert_is(self.node_settings.user_settings, None) assert_is(self.node_settings.folder, None) last_log = self.project.logs[-1] assert_equal(last_log.action, 'dropbox_node_deauthorized') params = last_log.params assert_in('node', params) assert_in('project', params) assert_in('folder', params) def test_set_folder(self): folder_name = 'queen/freddie' self.node_settings.set_folder(folder_name, auth=Auth(self.user)) self.node_settings.save() # Folder was set assert_equal(self.node_settings.folder, folder_name) # Log was saved last_log = self.project.logs[-1] assert_equal(last_log.action, 'dropbox_folder_selected') def test_set_user_auth(self): node_settings = DropboxNodeSettingsFactory() user_settings = DropboxUserSettingsFactory() node_settings.set_user_auth(user_settings) node_settings.save() assert_true(node_settings.has_auth) assert_equal(node_settings.user_settings, user_settings) # A log was saved last_log = node_settings.owner.logs[-1] assert_equal(last_log.action, 'dropbox_node_authorized') log_params = last_log.params assert_equal(log_params['folder'], node_settings.folder) assert_equal(log_params['node'], node_settings.owner._primary_key) assert_equal(last_log.user, user_settings.owner) def test_serialize_credentials(self): self.user_settings.access_token = 'secret' self.user_settings.save() credentials = self.node_settings.serialize_waterbutler_credentials() expected = {'token': self.node_settings.user_settings.access_token} assert_equal(credentials, expected) def test_serialize_credentials_not_authorized(self): self.node_settings.user_settings = None self.node_settings.save() with assert_raises(exceptions.AddonError): self.node_settings.serialize_waterbutler_credentials() def test_serialize_settings(self): settings = self.node_settings.serialize_waterbutler_settings() expected = {'folder': self.node_settings.folder} assert_equal(settings, expected) def test_serialize_settings_not_configured(self): self.node_settings.folder = None self.node_settings.save() with assert_raises(exceptions.AddonError): self.node_settings.serialize_waterbutler_settings() def test_create_log(self): action = 'file_added' path = 'pizza.nii' nlog = len(self.project.logs) self.node_settings.create_waterbutler_log( auth=Auth(user=self.user), action=action, metadata={'path': path}, ) self.project.reload() assert_equal(len(self.project.logs), nlog + 1) assert_equal( self.project.logs[-1].action, 'dropbox_{0}'.format(action), ) assert_equal( self.project.logs[-1].params['path'], os.path.join(self.node_settings.folder, path), ) def test_does_not_get_copied_to_registrations(self): registration = self.project.register_node( schema=None, auth=Auth(user=self.project.creator), template='Template1', data='hodor' ) assert_false(registration.has_addon('dropbox'))
class TestDropboxNodeSettingsModel(OsfTestCase): def setUp(self): super(TestDropboxNodeSettingsModel, self).setUp() self.user = UserFactory() self.user.add_addon('dropbox') self.user.save() self.user_settings = self.user.get_addon('dropbox') self.project = ProjectFactory() self.node_settings = DropboxNodeSettingsFactory( user_settings=self.user_settings, owner=self.project) def test_complete_true(self): self.node_settings.user_settings.access_token = 'seems legit' assert_true(self.node_settings.has_auth) assert_true(self.node_settings.complete) def test_complete_false(self): self.node_settings.user_settings.access_token = 'seems legit' self.node_settings.folder = None assert_true(self.node_settings.has_auth) assert_false(self.node_settings.complete) def test_complete_auth_false(self): self.node_settings.user_settings = None assert_false(self.node_settings.has_auth) assert_false(self.node_settings.complete) def test_fields(self): node_settings = DropboxNodeSettings(user_settings=self.user_settings) node_settings.save() assert_true(node_settings.user_settings) assert_equal(node_settings.user_settings.owner, self.user) assert_true(hasattr(node_settings, 'folder')) assert_true(hasattr(node_settings, 'registration_data')) def test_folder_defaults_to_none(self): node_settings = DropboxNodeSettings(user_settings=self.user_settings) node_settings.save() assert_is_none(node_settings.folder) def test_has_auth(self): settings = DropboxNodeSettings(user_settings=self.user_settings) settings.save() assert_false(settings.has_auth) settings.user_settings.access_token = '123abc' settings.user_settings.save() assert_true(settings.has_auth) def test_to_json(self): settings = self.node_settings user = UserFactory() result = settings.to_json(user) assert_equal(result['addon_short_name'], 'dropbox') def test_delete(self): assert_true(self.node_settings.user_settings) assert_true(self.node_settings.folder) old_logs = self.project.logs self.node_settings.delete() self.node_settings.save() assert_is(self.node_settings.user_settings, None) assert_is(self.node_settings.folder, None) assert_true(self.node_settings.deleted) assert_equal(self.project.logs, old_logs) def test_deauthorize(self): assert_true(self.node_settings.user_settings) assert_true(self.node_settings.folder) self.node_settings.deauthorize(auth=Auth(self.user)) self.node_settings.save() assert_is(self.node_settings.user_settings, None) assert_is(self.node_settings.folder, None) last_log = self.project.logs[-1] assert_equal(last_log.action, 'dropbox_node_deauthorized') params = last_log.params assert_in('node', params) assert_in('project', params) assert_in('folder', params) def test_set_folder(self): folder_name = 'queen/freddie' self.node_settings.set_folder(folder_name, auth=Auth(self.user)) self.node_settings.save() # Folder was set assert_equal(self.node_settings.folder, folder_name) # Log was saved last_log = self.project.logs[-1] assert_equal(last_log.action, 'dropbox_folder_selected') def test_set_user_auth(self): node_settings = DropboxNodeSettingsFactory() user_settings = DropboxUserSettingsFactory() node_settings.set_user_auth(user_settings) node_settings.save() assert_true(node_settings.has_auth) assert_equal(node_settings.user_settings, user_settings) # A log was saved last_log = node_settings.owner.logs[-1] assert_equal(last_log.action, 'dropbox_node_authorized') log_params = last_log.params assert_equal(log_params['folder'], node_settings.folder) assert_equal(log_params['node'], node_settings.owner._primary_key) assert_equal(last_log.user, user_settings.owner) def test_serialize_credentials(self): self.user_settings.access_token = 'secret' self.user_settings.save() credentials = self.node_settings.serialize_waterbutler_credentials() expected = {'token': self.node_settings.user_settings.access_token} assert_equal(credentials, expected) def test_serialize_credentials_not_authorized(self): self.node_settings.user_settings = None self.node_settings.save() with assert_raises(exceptions.AddonError): self.node_settings.serialize_waterbutler_credentials() def test_serialize_settings(self): settings = self.node_settings.serialize_waterbutler_settings() expected = {'folder': self.node_settings.folder} assert_equal(settings, expected) def test_serialize_settings_not_configured(self): self.node_settings.folder = None self.node_settings.save() with assert_raises(exceptions.AddonError): self.node_settings.serialize_waterbutler_settings() def test_create_log(self): action = 'file_added' path = 'pizza.nii' self.node_settings.folder = '/SomeOddPath' self.node_settings.save() nlog = len(self.project.logs) self.node_settings.create_waterbutler_log( auth=Auth(user=self.user), action=action, metadata={'path': path}, ) self.project.reload() assert_equal(len(self.project.logs), nlog + 1) assert_equal( self.project.logs[-1].action, 'dropbox_{0}'.format(action), ) assert_equal( self.project.logs[-1].params['path'], path, ) @mock.patch('website.archiver.tasks.archive') def test_does_not_get_copied_to_registrations(self, mock_archive): registration = self.project.register_node( schema=None, auth=Auth(user=self.project.creator), template='Template1', data='hodor') assert_false(registration.has_addon('dropbox'))
class TestS3ViewsConfig(OsfTestCase): def setUp(self): super(TestS3ViewsConfig, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.auth = ('test', self.user.api_keys[0]._primary_key) self.project = ProjectFactory(creator=self.user) self.project.add_addon('s3', auth=self.consolidated_auth) self.project.creator.add_addon('s3') self.user_settings = self.user.get_addon('s3') self.user_settings.access_key = 'We-Will-Rock-You' self.user_settings.secret_key = 'Idontknowanyqueensongs' self.user_settings.save() self.node_settings = self.project.get_addon('s3') self.node_settings.bucket = 'Sheer-Heart-Attack' self.node_settings.user_settings = self.project.creator.get_addon('s3') self.node_settings.save() self.node_url = '/api/v1/project/{0}/'.format(self.project._id) @mock.patch('website.addons.s3.views.config.does_bucket_exist') @mock.patch('website.addons.s3.views.config.adjust_cors') def test_s3_settings_no_bucket(self, mock_cors, mock_does_bucket_exist): mock_does_bucket_exist.return_value = False mock_cors.return_value = True url = self.project.api_url + 's3/settings/' rv = self.app.post_json(url, {}, expect_errors=True, auth=self.user.auth) assert_true('trouble' in rv.body) @mock.patch('website.addons.s3.views.config.does_bucket_exist') @mock.patch('website.addons.s3.views.config.adjust_cors') def test_s3_set_bucket(self, mock_cors, mock_exist): mock_cors.return_value = True mock_exist.return_value = True url = self.project.api_url + 's3/settings/' self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=self.user.auth, ) self.project.reload() self.node_settings.reload() assert_equal(self.node_settings.bucket, 'hammertofall') assert_equal(self.project.logs[-1].action, 's3_bucket_linked') def test_s3_set_bucket_no_settings(self): user = AuthUserFactory() self.project.add_contributor(user, save=True) url = self.project.api_url + 's3/settings/' res = self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True ) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_no_auth(self): user = AuthUserFactory() user.add_addon('s3') self.project.add_contributor(user, save=True) url = self.project.api_url + 's3/settings/' res = self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True ) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_already_authed(self): user = AuthUserFactory() user.add_addon('s3') user_settings = user.get_addon('s3') user_settings.access_key = 'foo' user_settings.secret_key = 'bar' user_settings.save() self.project.add_contributor(user, save=True) url = self.project.api_url + 's3/settings/' res = self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True ) assert_equal(res.status_code, http.BAD_REQUEST) @mock.patch('website.addons.s3.api.S3Wrapper.from_addon') def test_s3_set_bucket_registered(self, mock_from_addon): mock_from_addon.return_value = create_mock_wrapper() registration = self.project.register_node( None, self.consolidated_auth, '', '' ) url = registration.api_url + 's3/settings/' res = self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=self.user.auth, expect_errors=True, ) assert_equal(res.status_code, http.BAD_REQUEST) @mock.patch('website.addons.s3.views.config.has_access') @mock.patch('website.addons.s3.views.config.create_osf_user') def test_user_settings(self, mock_user, mock_access): mock_access.return_value = True mock_user.return_value = ( 'osf-user-12345', { 'access_key_id': 'scout', 'secret_access_key': 'ssshhhhhhhhh' } ) url = '/api/v1/settings/s3/' self.app.post_json( url, { 'access_key': 'scout', 'secret_key': 'Atticus' }, auth=self.user.auth ) self.user_settings.reload() assert_equals(self.user_settings.access_key, 'scout') @mock.patch('website.addons.s3.model.AddonS3UserSettings.remove_iam_user') def test_s3_remove_user_settings(self, mock_access): mock_access.return_value = True self.user_settings.access_key = 'to-kill-a-mocking-bucket' self.user_settings.secret_key = 'itsasecret' self.user_settings.save() url = '/api/v1/settings/s3/' self.app.delete(url, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, None) assert_equals(self.user_settings.secret_key, None) assert_equals(mock_access.call_count, 1) @mock.patch('website.addons.s3.model.AddonS3UserSettings.remove_iam_user') def test_s3_remove_user_settings_none(self, mock_access): self.user_settings.access_key = None self.user_settings.secret_key = None self.user_settings.save() url = '/api/v1/settings/s3/' self.app.delete(url, auth=self.user.auth) self.user_settings.reload() assert_equals(mock_access.call_count, 0) @mock.patch('website.addons.s3.views.config.has_access') def test_user_settings_no_auth(self, mock_access): mock_access.return_value = False url = '/api/v1/settings/s3/' rv = self.app.post_json(url, {}, auth=self.user.auth, expect_errors=True) assert_equals(rv.status_int, http.BAD_REQUEST) @mock.patch('website.addons.s3.views.config.has_access') @mock.patch('website.addons.s3.views.config.create_osf_user') def test_node_settings_no_user_settings(self, mock_user, mock_access): self.node_settings.user_settings = None self.node_settings.save() url = self.node_url + 's3/authorize/' mock_access.return_value = True mock_user.return_value = ( 'osf-user-12345', { 'access_key_id': 'scout', 'secret_access_key': 'ssshhhhhhhhh' } ) self.app.post_json(url, {'access_key': 'scout', 'secret_key': 'ssshhhhhhhhh'}, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, 'scout') def test_node_settings_no_user_settings_ui(self): self.node_settings.user_settings.access_key = None self.node_settings.user_settings = None self.node_settings.save() url = self.project.url + 'settings/' rv = self.app.get(url, auth=self.user.auth) assert_true('<label for="s3Addon">Access Key</label>' in rv.body) @mock.patch('website.addons.s3.model.get_bucket_drop_down') def test_node_settings_user_settings_ui(self, mock_dropdown): mock_dropdown.return_value = ['mybucket'] url = self.project.url + 'settings/' rv = self.app.get(url, auth=self.user.auth) assert_true('mybucket' in rv.body)
class TestS3ViewsConfig(OsfTestCase): def setUp(self): super(TestS3ViewsConfig, self).setUp() self.patcher = mock.patch('website.addons.s3.model.AddonS3UserSettings.is_valid', new=True) self.patcher.start() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.auth = self.user.auth self.project = ProjectFactory(creator=self.user) self.project.add_addon('s3', auth=self.consolidated_auth) self.project.creator.add_addon('s3') self.user_settings = self.user.get_addon('s3') self.user_settings.access_key = 'We-Will-Rock-You' self.user_settings.secret_key = 'Idontknowanyqueensongs' self.user_settings.save() self.node_settings = self.project.get_addon('s3') self.node_settings.bucket = 'Sheer-Heart-Attack' self.node_settings.user_settings = self.project.creator.get_addon('s3') self.node_settings.save() self.node_url = '/api/v1/project/{0}/'.format(self.project._id) def tearDown(self): super(TestS3ViewsConfig, self).tearDown() self.patcher.stop() def test_s3_settings_input_empty_keys(self): url = self.project.api_url_for('s3_post_user_settings') rv = self.app.post_json(url,{ 'access_key': '', 'secret_key': '' }, auth=self.user.auth, expect_errors=True) assert_equals(rv.status_int, http.BAD_REQUEST) assert_in('All the fields above are required.', rv.body) def test_s3_settings_input_empty_access_key(self): url = self.project.api_url_for('s3_post_user_settings') rv = self.app.post_json(url,{ 'access_key': '', 'secret_key': 'Non-empty-secret-key' }, auth=self.user.auth, expect_errors=True) assert_equals(rv.status_int, http.BAD_REQUEST) assert_in('All the fields above are required.', rv.body) def test_s3_settings_input_empty_secret_key(self): url = self.project.api_url_for('s3_post_user_settings') rv = self.app.post_json(url,{ 'access_key': 'Non-empty-access-key', 'secret_key': '' }, auth=self.user.auth, expect_errors=True) assert_equals(rv.status_int, http.BAD_REQUEST) assert_in('All the fields above are required.', rv.body) def test_s3_settings_no_bucket(self): rv = self.app.post_json( self.project.api_url_for('s3_post_node_settings'), {}, expect_errors=True, auth=self.user.auth ) assert_in('trouble', rv.body) @mock.patch('website.addons.s3.views.config.utils.bucket_exists') def test_s3_set_bucket(self, mock_exists): mock_exists.return_value = True url = self.project.api_url_for('s3_post_node_settings') self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=self.user.auth, ) self.project.reload() self.node_settings.reload() assert_equal(self.node_settings.bucket, 'hammertofall') assert_equal(self.project.logs[-1].action, 's3_bucket_linked') def test_s3_set_bucket_no_settings(self): user = AuthUserFactory() self.project.add_contributor(user, save=True) url = self.project.api_url_for('s3_post_node_settings') res = self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True ) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_no_auth(self): user = AuthUserFactory() user.add_addon('s3') self.project.add_contributor(user, save=True) url = self.project.api_url_for('s3_post_node_settings') res = self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True ) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_already_authed(self): user = AuthUserFactory() user.add_addon('s3') user_settings = user.get_addon('s3') user_settings.access_key = 'foo' user_settings.secret_key = 'bar' user_settings.save() self.project.add_contributor(user, save=True) url = self.project.api_url_for('s3_post_node_settings') res = self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True ) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_registered(self): registration = self.project.register_node( None, self.consolidated_auth, '', '' ) url = registration.api_url_for('s3_post_node_settings') res = self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=self.user.auth, expect_errors=True, ) assert_equal(res.status_code, http.BAD_REQUEST) @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=True) def test_user_settings(self, _): url = self.project.api_url_for('s3_post_user_settings') self.app.post_json( url, { 'access_key': 'Steven Hawking', 'secret_key': 'Atticus Fitch killing mocking' }, auth=self.user.auth ) self.user_settings.reload() assert_equals(self.user_settings.access_key, 'Steven Hawking') assert_equals(self.user_settings.secret_key, 'Atticus Fitch killing mocking') @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=True) def test_user_settings_when_user_does_not_have_addon(self, _): user = AuthUserFactory() url = self.project.api_url_for('s3_post_user_settings') self.app.post_json( url, { 'access_key': 'ABCDEFG', 'secret_key': 'We are the champions' }, auth=user.auth ) user.reload() user_settings = user.get_addon('s3') assert_equals(user_settings.access_key, 'ABCDEFG') assert_equals(user_settings.secret_key, 'We are the champions') def test_s3_remove_user_settings(self): self.user_settings.access_key = 'to-kill-a-mocking-bucket' self.user_settings.secret_key = 'itsasecret' self.user_settings.save() url = api_url_for('s3_delete_user_settings') self.app.delete(url, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, None) assert_equals(self.user_settings.secret_key, None) # Last log has correct action and user self.project.reload() last_project_log = self.project.logs[-1] assert_equal(last_project_log.action, 's3_node_deauthorized') assert_equal(last_project_log.user, self.user) def test_s3_remove_user_settings_none(self): self.user_settings.access_key = None self.user_settings.secret_key = None self.user_settings.save() url = api_url_for('s3_delete_user_settings') self.app.delete(url, auth=self.user.auth) self.user_settings.reload() @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=False) def test_user_settings_cant_list(self, mock_can_list): url = api_url_for('s3_post_user_settings') rv = self.app.post_json(url, { 'access_key': 'aldkjf', 'secret_key': 'las' }, auth=self.user.auth, expect_errors=True) assert_equals(rv.status_int, http.BAD_REQUEST) assert_in('Unable to list buckets.', rv.body) @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=True) def test_node_settings_no_user_settings(self, mock_can_list): self.node_settings.user_settings = None self.node_settings.save() url = self.project.api_url_for('s3_authorize_node') self.app.post_json(url, {'access_key': 'scout', 'secret_key': 'ssshhhhhhhhh'}, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, 'scout') @mock.patch('website.addons.s3.views.config.utils.get_bucket_names') def test_s3_bucket_list(self, mock_bucket_list): fake_buckets = [] for _ in range(10): fake_bucket = mock.Mock() fake_bucket.name = fake.domain_word() fake_bucket.append(fake_bucket) mock_bucket_list.return_value = fake_buckets url = self.node_settings.owner.api_url_for('s3_get_bucket_list') ret = self.app.get(url, auth=self.user.auth) assert_equals(ret.json, {'buckets': [bucket.name for bucket in fake_buckets]}) def test_s3_remove_node_settings_owner(self): url = self.node_settings.owner.api_url_for('s3_delete_node_settings') ret = self.app.delete(url, auth=self.user.auth) assert_equal(ret.json['has_bucket'], False) assert_equal(ret.json['node_has_auth'], False) def test_s3_remove_node_settings_unauthorized(self): url = self.node_settings.owner.api_url_for('s3_delete_node_settings') ret = self.app.delete(url, auth=None, expect_errors=True) assert_equal(ret.status_code, 401) def test_s3_get_node_settings_owner(self): url = self.node_settings.owner.api_url_for('s3_get_node_settings') res = self.app.get(url, auth=self.user.auth) result = res.json['result'] assert_equal(result['node_has_auth'], True) assert_equal(result['user_is_owner'], True) assert_equal(result['bucket'], self.node_settings.bucket) def test_s3_get_node_settings_not_owner(self): url = self.node_settings.owner.api_url_for('s3_get_node_settings') non_owner = AuthUserFactory() self.project.add_contributor(non_owner, save=True, permissions=['write']) res = self.app.get(url, auth=non_owner.auth) result = res.json['result'] assert_equal(result['bucket'], self.node_settings.bucket) assert_equal(result['node_has_auth'], True) assert_equal(result['user_is_owner'], False) def test_s3_get_node_settings_unauthorized(self): url = self.node_settings.owner.api_url_for('s3_get_node_settings') unauthorized = AuthUserFactory() ret = self.app.get(url, auth=unauthorized.auth, expect_errors=True) assert_equal(ret.status_code, 403) @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=True) def test_s3_authorize_node_valid(self, _): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth) assert_equal(res.json['node_has_auth'], True) def test_s3_authorize_node_malformed(self): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=False) def test_s3_authorize_node_invalid(self, _): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_in('Unable to list buckets', res.json['message']) assert_equal(res.status_code, 400) def test_s3_authorize_node_unauthorized(self): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } unauthorized = AuthUserFactory() res = self.app.post_json(url, cred, auth=unauthorized.auth, expect_errors=True) assert_equal(res.status_code, 403) @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=True) def test_s3_authorize_user_valid(self, _): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth) assert_equal(res.status_code, 200) def test_s3_authorize_user_malformed(self): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=False) def test_s3_authorize_user_invalid(self, _): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_in('Unable to list buckets', res.json['message']) assert_equal(res.status_code, 400) def test_s3_authorize_input_empty_keys(self): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': '', 'secret_key': '', } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_in('All the fields above are required', res.json['message']) assert_equal(res.status_code, 400) def test_s3_authorize_input_empty_access_key(self): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': '', 'secret_key': 'Non-empty-secret-key', } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_in('All the fields above are required', res.json['message']) assert_equal(res.status_code, 400) def test_s3_authorize_input_empty_secret_key(self): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': 'Non-empty-access-key', 'secret_key': '', } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_in('All the fields above are required', res.json['message']) assert_equal(res.status_code, 400) @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=True) def test_s3_node_import_auth_authorized(self, _): url = self.project.api_url_for('s3_node_import_auth') self.node_settings.deauthorize(auth=None, save=True) res = self.app.post(url, auth=self.user.auth) assert_equal(res.json['node_has_auth'], True) assert_equal(res.json['user_is_owner'], True) def test_s3_node_import_auth_unauthorized(self): url = self.project.api_url_for('s3_node_import_auth') self.node_settings.deauthorize(auth=None, save=True) unauthorized = AuthUserFactory() res = self.app.post(url, auth=unauthorized.auth, expect_errors=True) assert_equal(res.status_code, 403)
class TestCallbacks(OsfTestCase): def setUp(self): super(TestCallbacks, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.auth = self.user.auth self.project = ProjectFactory(creator=self.user) self.non_authenticator = AuthUserFactory() self.project.add_contributor( contributor=self.non_authenticator, auth=Auth(self.project.creator), ) self.project.add_addon('figshare', auth=self.consolidated_auth) self.project.creator.add_addon('figshare') self.node_settings = self.project.get_addon('figshare') self.user_settings = self.project.creator.get_addon('figshare') self.user_settings.oauth_access_token = 'legittoken' self.user_settings.oauth_access_token_secret = 'legittoken' self.user_settings.save() self.node_settings.user_settings = self.user_settings self.node_settings.figshare_id = '123456' self.node_settings.figshare_type = 'project' self.node_settings.figshare_title = 'singlefile' self.node_settings.save() def test_update_fields_project(self): num_logs = len(self.project.logs) # try updating fields newfields = { 'type': 'project', 'id': '313131', 'name': 'A PROJECT' } self.node_settings.update_fields(newfields, self.project, Auth(self.project.creator)) #check for updated assert_equals(self.node_settings.figshare_id, '313131') assert_equals(self.node_settings.figshare_type, 'project') assert_equals(self.node_settings.figshare_title, 'A PROJECT') # check for log added assert_equals(len(self.project.logs), num_logs + 1) def test_update_fields_fileset(self): num_logs = len(self.project.logs) # try updating fields newfields = { 'type': 'fileset', 'id': '313131', 'name': 'A FILESET' } self.node_settings.update_fields(newfields, self.project, Auth(self.project.creator)) #check for updated assert_equals(self.node_settings.figshare_id, '313131') assert_equals(self.node_settings.figshare_type, 'fileset') assert_equals(self.node_settings.figshare_title, 'A FILESET') # check for log added assert_equals(len(self.project.logs), num_logs + 1) def test_update_fields_some_missing(self): num_logs = len(self.project.logs) # try updating fields newfields = { 'type': 'project', 'id': '313131', 'name': 'A PROJECT' } self.node_settings.update_fields(newfields, self.project, Auth(self.project.creator)) #check for updated assert_equals(self.node_settings.figshare_id, '313131') assert_equals(self.node_settings.figshare_title, 'A PROJECT') # check for log added assert_equals(len(self.project.logs), num_logs + 1) def test_update_fields_invalid(self): num_logs = len(self.project.logs) # try updating fields newfields = { 'adad': 131313, 'i1513': '313131', 'titladad': 'A PROJECT' } self.node_settings.update_fields(newfields, self.project, Auth(self.project.creator)) #check for updated assert_equals(self.node_settings.figshare_id, '123456') assert_equals(self.node_settings.figshare_type, 'project') assert_equals(self.node_settings.figshare_title, 'singlefile') # check for log added assert_equals(len(self.project.logs), num_logs) def test_api_url_no_user(self): self.node_settings.user_settings = None self.node_settings.save() assert_equal(self.node_settings.api_url, figshare_settings.API_URL) def test_api_url(self): assert_equal(self.node_settings.api_url, figshare_settings.API_OAUTH_URL) def test_before_register_linked_content(self): assert_false( self.node_settings.before_register( self.project, self.project.creator ) is None ) def test_before_register_no_linked_content(self): self.node_settings.figshare_id = None assert_true( self.node_settings.before_register( self.project, self.project.creator ) is None ) def test_before_remove_contributor_authenticator(self): message = self.node_settings.before_remove_contributor( self.project, self.project.creator ) assert_true(message) def test_before_remove_contributor_not_authenticator(self): message = self.node_settings.before_remove_contributor( self.project, self.non_authenticator ) assert_false(message) def test_after_remove_contributor_authenticator_not_self(self): auth = Auth(user=self.non_authenticator) msg = self.node_settings.after_remove_contributor( self.project, self.project.creator, auth ) assert_in( self.project.project_or_component, msg ) assert_equal( self.node_settings.user_settings, None ) assert_in("You can re-authenticate", msg) def test_after_remove_contributor_authenticator_self(self): msg = self.node_settings.after_remove_contributor( self.project, self.project.creator, self.consolidated_auth ) assert_in( self.project.title, msg ) assert_equal( self.node_settings.user_settings, None ) assert_not_in("You can re-authenticate", msg) def test_after_fork_authenticator(self): fork = ProjectFactory() clone, message = self.node_settings.after_fork( self.project, fork, self.project.creator, ) assert_equal( self.node_settings.user_settings, clone.user_settings, ) def test_after_fork_not_authenticator(self): fork = ProjectFactory() clone, message = self.node_settings.after_fork( self.project, fork, self.non_authenticator, ) assert_equal( clone.user_settings, None, ) def test_after_delete(self): self.project.remove_node(Auth(user=self.project.creator)) # Ensure that changes to node settings have been saved self.node_settings.reload() assert_true(self.node_settings.user_settings is None) assert_true(self.node_settings.figshare_id is None) assert_true(self.node_settings.figshare_type is None) assert_true(self.node_settings.figshare_title is None) @mock.patch('website.archiver.tasks.archive') @mock.patch('website.addons.figshare.model.AddonFigShareNodeSettings.archive_errors') def test_does_not_get_copied_to_registrations(self, mock_errors, mock_archive): registration = self.project.register_node( schema=None, auth=Auth(user=self.project.creator), template='Template1', data='hodor' ) assert_false(registration.has_addon('figshare'))
class TestS3ViewsConfig(OsfTestCase): def setUp(self): super(TestS3ViewsConfig, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.auth = ('test', self.user.api_keys[0]._primary_key) self.project = ProjectFactory(creator=self.user) self.project.add_addon('s3', auth=self.consolidated_auth) self.project.creator.add_addon('s3') self.user_settings = self.user.get_addon('s3') self.user_settings.access_key = 'We-Will-Rock-You' self.user_settings.secret_key = 'Idontknowanyqueensongs' self.user_settings.save() self.node_settings = self.project.get_addon('s3') self.node_settings.bucket = 'Sheer-Heart-Attack' self.node_settings.user_settings = self.project.creator.get_addon('s3') self.node_settings.save() self.node_url = '/api/v1/project/{0}/'.format(self.project._id) @mock.patch('website.addons.s3.views.config.does_bucket_exist') @mock.patch('website.addons.s3.views.config.adjust_cors') def test_s3_settings_no_bucket(self, mock_cors, mock_does_bucket_exist): mock_does_bucket_exist.return_value = False mock_cors.return_value = True url = self.project.api_url + 's3/settings/' rv = self.app.post_json(url, {}, expect_errors=True, auth=self.user.auth) assert_true('trouble' in rv.body) @mock.patch('website.addons.s3.views.config.does_bucket_exist') @mock.patch('website.addons.s3.views.config.adjust_cors') @mock.patch('website.addons.s3.utils.get_bucket_drop_down') def test_s3_set_bucket(self, mock_cors, mock_exist, mock_dropdown): mock_cors.return_value = True mock_exist.return_value = True mock_dropdown.return_value = ['mybucket'] url = self.project.api_url_for('s3_node_settings') self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=self.user.auth, ) self.project.reload() self.node_settings.reload() assert_equal(self.node_settings.bucket, 'hammertofall') assert_equal(self.project.logs[-1].action, 's3_bucket_linked') def test_s3_set_bucket_no_settings(self): user = AuthUserFactory() self.project.add_contributor(user, save=True) url = self.project.api_url + 's3/settings/' res = self.app.post_json(url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_no_auth(self): user = AuthUserFactory() user.add_addon('s3') self.project.add_contributor(user, save=True) url = self.project.api_url + 's3/settings/' res = self.app.post_json(url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_already_authed(self): user = AuthUserFactory() user.add_addon('s3') user_settings = user.get_addon('s3') user_settings.access_key = 'foo' user_settings.secret_key = 'bar' user_settings.save() self.project.add_contributor(user, save=True) url = self.project.api_url + 's3/settings/' res = self.app.post_json(url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True) assert_equal(res.status_code, http.BAD_REQUEST) @mock.patch('website.addons.s3.api.S3Wrapper.from_addon') def test_s3_set_bucket_registered(self, mock_from_addon): mock_from_addon.return_value = create_mock_wrapper() registration = self.project.register_node(None, self.consolidated_auth, '', '') url = registration.api_url + 's3/settings/' res = self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=self.user.auth, expect_errors=True, ) assert_equal(res.status_code, http.BAD_REQUEST) @mock.patch('website.addons.s3.views.config.has_access') @mock.patch('website.addons.s3.views.config.create_osf_user') def test_user_settings(self, mock_user, mock_access): mock_access.return_value = True mock_user.return_value = ('osf-user-12345', { 'access_key_id': 'scout', 'secret_access_key': 'ssshhhhhhhhh' }) url = '/api/v1/settings/s3/' self.app.post_json(url, { 'access_key': 'scout', 'secret_key': 'Atticus' }, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, 'scout') @mock.patch('website.addons.s3.model.AddonS3UserSettings.remove_iam_user') def test_s3_remove_user_settings(self, mock_access): mock_access.return_value = True self.user_settings.access_key = 'to-kill-a-mocking-bucket' self.user_settings.secret_key = 'itsasecret' self.user_settings.save() url = api_url_for('s3_remove_user_settings') self.app.delete(url, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, None) assert_equals(self.user_settings.secret_key, None) assert_equals(mock_access.call_count, 1) @mock.patch('website.addons.s3.model.AddonS3UserSettings.remove_iam_user') def test_s3_remove_user_settings_none(self, mock_access): self.user_settings.access_key = None self.user_settings.secret_key = None self.user_settings.save() url = api_url_for('s3_remove_user_settings') self.app.delete(url, auth=self.user.auth) self.user_settings.reload() assert_equals(mock_access.call_count, 0) @mock.patch('website.addons.s3.views.config.has_access') def test_user_settings_no_auth(self, mock_access): mock_access.return_value = False url = '/api/v1/settings/s3/' rv = self.app.post_json(url, {}, auth=self.user.auth, expect_errors=True) assert_equals(rv.status_int, http.BAD_REQUEST) @mock.patch('website.addons.s3.utils.get_bucket_drop_down') @mock.patch('website.addons.s3.views.config.has_access') @mock.patch('website.addons.s3.views.config.create_osf_user') def test_node_settings_no_user_settings(self, mock_user, mock_access, mock_dropdown): self.node_settings.user_settings = None self.node_settings.save() url = self.node_url + 's3/authorize/' mock_access.return_value = True mock_user.return_value = ('osf-user-12345', { 'access_key_id': 'scout', 'secret_access_key': 'ssshhhhhhhhh' }) mock_dropdown.return_value = ['mybucket'] self.app.post_json(url, { 'access_key': 'scout', 'secret_key': 'ssshhhhhhhhh' }, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, 'scout') @mock.patch('website.addons.s3.utils.get_bucket_drop_down') def test_node_settings_no_user_settings_ui(self, mock_dropdown): mock_dropdown.return_value = ['mybucket'] self.node_settings.user_settings.access_key = None self.node_settings.user_settings = None self.node_settings.save() url = self.project.url + 'settings/' rv = self.app.get(url, auth=self.user.auth) assert_true('<label for="s3Addon">Access Key</label>' in rv.body) @mock.patch('website.addons.s3.utils.get_bucket_list') def test_s3_bucket_list(self, mock_bucket_list): fake_buckets = [ MockS3Bucket(name=fake.domain_word()) for i in range(10) ] mock_bucket_list.return_value = fake_buckets url = self.node_settings.owner.api_url_for('s3_bucket_list') ret = self.app.get(url, auth=self.user.auth) assert_equals(ret.json, {'buckets': [bucket.name for bucket in fake_buckets]}) def test_s3_remove_node_settings_owner(self): url = self.node_settings.owner.api_url_for('s3_remove_node_settings') ret = self.app.delete(url, auth=self.user.auth) assert_equal(ret.json['has_bucket'], False) assert_equal(ret.json['node_has_auth'], False) def test_s3_remove_node_settings_unauthorized(self): url = self.node_settings.owner.api_url_for('s3_remove_node_settings') ret = self.app.delete(url, auth=None, expect_errors=True) assert_equal(ret.status_code, 401) def test_s3_get_node_settings_owner(self): url = self.node_settings.owner.api_url_for('s3_get_node_settings') res = self.app.get(url, auth=self.user.auth) expected_bucket = self.node_settings.bucket expected_node_has_auth = True expected_user_is_owner = True result = res.json['result'] assert_equal(result['bucket'], expected_bucket) assert_equal(result['node_has_auth'], expected_node_has_auth) assert_equal(result['user_is_owner'], expected_user_is_owner) def test_s3_get_node_settings_not_owner(self): url = self.node_settings.owner.api_url_for('s3_get_node_settings') non_owner = AuthUserFactory() self.project.add_contributor(non_owner, save=True, permissions=['write']) res = self.app.get(url, auth=non_owner.auth) expected_bucket = self.node_settings.bucket expected_node_has_auth = True expected_user_is_owner = False result = res.json['result'] assert_equal(result['bucket'], expected_bucket) assert_equal(result['node_has_auth'], expected_node_has_auth) assert_equal(result['user_is_owner'], expected_user_is_owner) def test_s3_get_node_settings_unauthorized(self): url = self.node_settings.owner.api_url_for('s3_get_node_settings') unauthorized = AuthUserFactory() ret = self.app.get(url, auth=unauthorized.auth, expect_errors=True) assert_equal(ret.status_code, 403) @mock.patch('website.addons.s3.views.config.add_s3_auth') def test_s3_authorize_node_valid(self, mock_add): mock_add.return_value = True url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth) assert_equal(res.json['node_has_auth'], True) def test_s3_authorize_node_invalid(self): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) @mock.patch('website.addons.s3.views.config.add_s3_auth') def test_s3_authorize_node_malformed(self, mock_add): mock_add.return_value = False url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_equal(res.json['message'], 'Incorrect credentials') assert_equal(res.status_code, 400) @mock.patch('website.addons.s3.views.config.add_s3_auth') def test_s3_authorize_node_unauthorized(self, mock_add): mock_add.return_value = True url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } unauthorized = AuthUserFactory() res = self.app.post_json(url, cred, auth=unauthorized.auth, expect_errors=True) assert_equal(res.status_code, 403) @mock.patch('website.addons.s3.views.config.add_s3_auth') def test_s3_authorize_user_valid(self, mock_add): mock_add.return_value = True url = self.project.api_url_for('s3_authorize_user') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth) assert_equal(res.json, {}) def test_s3_authorize_user_invalid(self): url = self.project.api_url_for('s3_authorize_user') cred = { 'access_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) @mock.patch('website.addons.s3.views.config.add_s3_auth') def test_s3_authorize_user_malformed(self, mock_add): mock_add.return_value = False url = self.project.api_url_for('s3_authorize_user') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_equal(res.json['message'], 'Incorrect credentials') assert_equal(res.status_code, 400) def test_s3_node_import_auth_authorized(self): url = self.project.api_url_for('s3_node_import_auth') self.node_settings.deauthorize(auth=None, save=True) res = self.app.post(url, auth=self.user.auth) assert_equal(res.json['node_has_auth'], True) assert_equal(res.json['user_is_owner'], True) def test_s3_node_import_auth_unauthorized(self): url = self.project.api_url_for('s3_node_import_auth') self.node_settings.deauthorize(auth=None, save=True) unauthorized = AuthUserFactory() res = self.app.post(url, auth=unauthorized.auth, expect_errors=True) assert_equal(res.status_code, 403)
class TestS3ViewsConfig(OsfTestCase): def setUp(self): super(TestS3ViewsConfig, self).setUp() self.patcher = mock.patch( 'website.addons.s3.model.AddonS3UserSettings.is_valid', new=True) self.patcher.start() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.auth = self.user.auth self.project = ProjectFactory(creator=self.user) self.project.add_addon('s3', auth=self.consolidated_auth) self.project.creator.add_addon('s3') self.user_settings = self.user.get_addon('s3') self.user_settings.access_key = 'We-Will-Rock-You' self.user_settings.secret_key = 'Idontknowanyqueensongs' self.user_settings.save() self.node_settings = self.project.get_addon('s3') self.node_settings.bucket = 'Sheer-Heart-Attack' self.node_settings.user_settings = self.project.creator.get_addon('s3') self.node_settings.save() self.node_url = '/api/v1/project/{0}/'.format(self.project._id) def tearDown(self): super(TestS3ViewsConfig, self).tearDown() self.patcher.stop() def test_s3_settings_input_empty_keys(self): url = self.project.api_url_for('s3_post_user_settings') rv = self.app.post_json(url, { 'access_key': '', 'secret_key': '' }, auth=self.user.auth, expect_errors=True) assert_equals(rv.status_int, http.BAD_REQUEST) assert_in('All the fields above are required.', rv.body) def test_s3_settings_input_empty_access_key(self): url = self.project.api_url_for('s3_post_user_settings') rv = self.app.post_json(url, { 'access_key': '', 'secret_key': 'Non-empty-secret-key' }, auth=self.user.auth, expect_errors=True) assert_equals(rv.status_int, http.BAD_REQUEST) assert_in('All the fields above are required.', rv.body) def test_s3_settings_input_empty_secret_key(self): url = self.project.api_url_for('s3_post_user_settings') rv = self.app.post_json(url, { 'access_key': 'Non-empty-access-key', 'secret_key': '' }, auth=self.user.auth, expect_errors=True) assert_equals(rv.status_int, http.BAD_REQUEST) assert_in('All the fields above are required.', rv.body) def test_s3_settings_no_bucket(self): rv = self.app.post_json( self.project.api_url_for('s3_post_node_settings'), {}, expect_errors=True, auth=self.user.auth) assert_in('trouble', rv.body) @mock.patch('website.addons.s3.views.config.utils.bucket_exists') def test_s3_set_bucket(self, mock_exists): mock_exists.return_value = True url = self.project.api_url_for('s3_post_node_settings') self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=self.user.auth, ) self.project.reload() self.node_settings.reload() assert_equal(self.node_settings.bucket, 'hammertofall') assert_equal(self.project.logs[-1].action, 's3_bucket_linked') def test_s3_set_bucket_no_settings(self): user = AuthUserFactory() self.project.add_contributor(user, save=True) url = self.project.api_url_for('s3_post_node_settings') res = self.app.post_json(url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_no_auth(self): user = AuthUserFactory() user.add_addon('s3') self.project.add_contributor(user, save=True) url = self.project.api_url_for('s3_post_node_settings') res = self.app.post_json(url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_already_authed(self): user = AuthUserFactory() user.add_addon('s3') user_settings = user.get_addon('s3') user_settings.access_key = 'foo' user_settings.secret_key = 'bar' user_settings.save() self.project.add_contributor(user, save=True) url = self.project.api_url_for('s3_post_node_settings') res = self.app.post_json(url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_registered(self): registration = self.project.register_node(get_default_metaschema(), self.consolidated_auth, '', '') url = registration.api_url_for('s3_post_node_settings') res = self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=self.user.auth, expect_errors=True, ) assert_equal(res.status_code, http.BAD_REQUEST) @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=True) def test_user_settings(self, _): url = self.project.api_url_for('s3_post_user_settings') self.app.post_json(url, { 'access_key': 'Steven Hawking', 'secret_key': 'Atticus Fitch killing mocking' }, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, 'Steven Hawking') assert_equals(self.user_settings.secret_key, 'Atticus Fitch killing mocking') @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=True) def test_user_settings_when_user_does_not_have_addon(self, _): user = AuthUserFactory() url = self.project.api_url_for('s3_post_user_settings') self.app.post_json(url, { 'access_key': 'ABCDEFG', 'secret_key': 'We are the champions' }, auth=user.auth) user.reload() user_settings = user.get_addon('s3') assert_equals(user_settings.access_key, 'ABCDEFG') assert_equals(user_settings.secret_key, 'We are the champions') def test_s3_remove_user_settings(self): self.user_settings.access_key = 'to-kill-a-mocking-bucket' self.user_settings.secret_key = 'itsasecret' self.user_settings.save() url = api_url_for('s3_delete_user_settings') self.app.delete(url, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, None) assert_equals(self.user_settings.secret_key, None) # Last log has correct action and user self.project.reload() last_project_log = self.project.logs[-1] assert_equal(last_project_log.action, 's3_node_deauthorized') assert_equal(last_project_log.user, self.user) def test_s3_remove_user_settings_none(self): self.user_settings.access_key = None self.user_settings.secret_key = None self.user_settings.save() url = api_url_for('s3_delete_user_settings') self.app.delete(url, auth=self.user.auth) self.user_settings.reload() @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=False) def test_user_settings_cant_list(self, mock_can_list): url = api_url_for('s3_post_user_settings') rv = self.app.post_json(url, { 'access_key': 'aldkjf', 'secret_key': 'las' }, auth=self.user.auth, expect_errors=True) assert_equals(rv.status_int, http.BAD_REQUEST) assert_in('Unable to list buckets.', rv.body) @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=True) def test_node_settings_no_user_settings(self, mock_can_list): self.node_settings.user_settings = None self.node_settings.save() url = self.project.api_url_for('s3_authorize_node') self.app.post_json(url, { 'access_key': 'scout', 'secret_key': 'ssshhhhhhhhh' }, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, 'scout') @mock.patch('website.addons.s3.views.config.utils.get_bucket_names') def test_s3_bucket_list(self, mock_bucket_list): fake_buckets = [] for _ in range(10): fake_bucket = mock.Mock() fake_bucket.name = fake.domain_word() fake_bucket.append(fake_bucket) mock_bucket_list.return_value = fake_buckets url = self.node_settings.owner.api_url_for('s3_get_bucket_list') ret = self.app.get(url, auth=self.user.auth) assert_equals(ret.json, {'buckets': [bucket.name for bucket in fake_buckets]}) def test_s3_remove_node_settings_owner(self): url = self.node_settings.owner.api_url_for('s3_delete_node_settings') ret = self.app.delete(url, auth=self.user.auth) assert_equal(ret.json['has_bucket'], False) assert_equal(ret.json['node_has_auth'], False) def test_s3_remove_node_settings_unauthorized(self): url = self.node_settings.owner.api_url_for('s3_delete_node_settings') ret = self.app.delete(url, auth=None, expect_errors=True) assert_equal(ret.status_code, 401) def test_s3_get_node_settings_owner(self): url = self.node_settings.owner.api_url_for('s3_get_node_settings') res = self.app.get(url, auth=self.user.auth) result = res.json['result'] assert_equal(result['node_has_auth'], True) assert_equal(result['user_is_owner'], True) assert_equal(result['bucket'], self.node_settings.bucket) def test_s3_get_node_settings_not_owner(self): url = self.node_settings.owner.api_url_for('s3_get_node_settings') non_owner = AuthUserFactory() self.project.add_contributor(non_owner, save=True, permissions=['write']) res = self.app.get(url, auth=non_owner.auth) result = res.json['result'] assert_equal(result['bucket'], self.node_settings.bucket) assert_equal(result['node_has_auth'], True) assert_equal(result['user_is_owner'], False) def test_s3_get_node_settings_unauthorized(self): url = self.node_settings.owner.api_url_for('s3_get_node_settings') unauthorized = AuthUserFactory() ret = self.app.get(url, auth=unauthorized.auth, expect_errors=True) assert_equal(ret.status_code, 403) @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=True) def test_s3_authorize_node_valid(self, _): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth) assert_equal(res.json['node_has_auth'], True) def test_s3_authorize_node_malformed(self): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=False) def test_s3_authorize_node_invalid(self, _): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_in('Unable to list buckets', res.json['message']) assert_equal(res.status_code, 400) def test_s3_authorize_node_unauthorized(self): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } unauthorized = AuthUserFactory() res = self.app.post_json(url, cred, auth=unauthorized.auth, expect_errors=True) assert_equal(res.status_code, 403) @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=True) def test_s3_authorize_user_valid(self, _): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth) assert_equal(res.status_code, 200) def test_s3_authorize_user_malformed(self): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=False) def test_s3_authorize_user_invalid(self, _): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_in('Unable to list buckets', res.json['message']) assert_equal(res.status_code, 400) def test_s3_authorize_input_empty_keys(self): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': '', 'secret_key': '', } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_in('All the fields above are required', res.json['message']) assert_equal(res.status_code, 400) def test_s3_authorize_input_empty_access_key(self): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': '', 'secret_key': 'Non-empty-secret-key', } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_in('All the fields above are required', res.json['message']) assert_equal(res.status_code, 400) def test_s3_authorize_input_empty_secret_key(self): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': 'Non-empty-access-key', 'secret_key': '', } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_in('All the fields above are required', res.json['message']) assert_equal(res.status_code, 400) @mock.patch('website.addons.s3.views.config.utils.can_list', return_value=True) def test_s3_node_import_auth_authorized(self, _): url = self.project.api_url_for('s3_node_import_auth') self.node_settings.deauthorize(auth=None, save=True) res = self.app.post(url, auth=self.user.auth) assert_equal(res.json['node_has_auth'], True) assert_equal(res.json['user_is_owner'], True) def test_s3_node_import_auth_unauthorized(self): url = self.project.api_url_for('s3_node_import_auth') self.node_settings.deauthorize(auth=None, save=True) unauthorized = AuthUserFactory() res = self.app.post(url, auth=unauthorized.auth, expect_errors=True) assert_equal(res.status_code, 403)
class TestAddonFileViews(OsfTestCase): @classmethod def setUpClass(cls): super(TestAddonFileViews, cls).setUpClass() PROVIDER_MAP['github'] = [TestFolder, TestFile, TestFileNode] TestFileNode.provider = 'github' def setUp(self): super(TestAddonFileViews, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.user.add_addon('github') self.project.add_addon('github', auth=Auth(self.user)) self.user_addon = self.user.get_addon('github') self.node_addon = self.project.get_addon('github') self.oauth = GitHubAccountFactory() self.oauth.save() self.user.external_accounts.append(self.oauth) self.user.save() self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth self.node_addon.repo = 'Truth' self.node_addon.user = '******' self.node_addon.save() @classmethod def tearDownClass(cls): super(TestAddonFileViews, cls).tearDownClass() PROVIDER_MAP['github'] = [models.GithubFolder, models.GithubFile, models.GithubFileNode] del PROVIDER_MAP['test_addons'] TrashedFileNode.remove() def get_test_file(self): version = models.FileVersion(identifier='1') version.save() versions = [version] ret = TestFile( name='Test', node=self.project, path='/test/Test', materialized_path='/test/Test', versions=versions ) ret.save() return ret def get_second_test_file(self): version = models.FileVersion(identifier='1') version.save() ret = TestFile( name='Test2', node=self.project, path='/test/Test2', materialized_path='/test/Test2', versions=[version] ) ret.save() return ret def get_mako_return(self): ret = serialize_node(self.project, Auth(self.user), primary=True) ret.update({ 'error': '', 'provider': '', 'file_path': '', 'sharejs_uuid': '', 'private': '', 'urls': { 'files': '', 'render': '', 'sharejs': '', 'mfr': '', 'gravatar': '', 'external': '', 'archived_from': '', }, 'size': '', 'extra': '', 'file_name': '', 'materialized_path': '', 'file_id': '', }) ret.update(rubeus.collect_addon_assets(self.project)) return ret def test_redirects_to_guid(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github' ), auth=self.user.auth ) assert_equals(resp.status_code, 302) assert_equals(resp.location, 'http://*****:*****@mock.patch('website.addons.base.views.addon_view_file') def test_action_view_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/?action=view'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) @mock.patch('website.addons.base.views.addon_view_file') def test_no_action_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) def test_download_create_guid(self): file_node = self.get_test_file() assert_is(file_node.get_guid(), None) self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github', ), auth=self.user.auth ) assert_true(file_node.get_guid()) def test_view_file_does_not_delete_file_when_requesting_invalid_version(self): with mock.patch('website.addons.github.model.GitHubNodeSettings.is_private', new_callable=mock.PropertyMock) as mock_is_private: mock_is_private.return_value = False file_node = self.get_test_file() assert_is(file_node.get_guid(), None) url = self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github', ) # First view generated GUID self.app.get(url, auth=self.user.auth) self.app.get(url + '?version=invalid', auth=self.user.auth, expect_errors=True) assert_is_not_none(StoredFileNode.load(file_node._id)) assert_is_none(TrashedFileNode.load(file_node._id)) def test_unauthorized_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 401) def test_nonstorage_addons_raise(self): resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path='sillywiki', provider='wiki', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 400) def test_head_returns_url(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head('/{}/'.format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, version=None)) def test_head_returns_url_with_version(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head('/{}/?revision=1&foo=bar'.format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) # Note: version is added but us but all other url params are added as well assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, revision=1, version=None, foo='bar')) def test_nonexistent_addons_raise(self): path = 'cloudfiles' self.project.delete_addon('github', Auth(self.user)) self.project.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 400) def test_unauth_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 401) def test_delete_action_creates_trashed_file_node(self): file_node = self.get_test_file() payload = { 'provider': file_node.provider, 'metadata': { 'path': '/test/Test', 'materialized': '/test/Test' } } views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload) assert_false(StoredFileNode.load(file_node._id)) assert_true(TrashedFileNode.load(file_node._id)) def test_delete_action_for_folder_deletes_subfolders_and_creates_trashed_file_nodes(self): file_node = self.get_test_file() subfolder = TestFolder( name='folder', node=self.project, path='/test/folder/', materialized_path='/test/folder/', versions=[] ) subfolder.save() payload = { 'provider': file_node.provider, 'metadata': { 'path': '/test/', 'materialized': '/test/' } } views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload) assert_false(StoredFileNode.load(file_node._id)) assert_true(TrashedFileNode.load(file_node._id)) assert_false(StoredFileNode.load(subfolder._id)) @mock.patch('website.archiver.tasks.archive') def test_archived_from_url(self, mock_archive): file_node = self.get_test_file() second_file_node = self.get_second_test_file() file_node.copied_from = second_file_node registered_node = self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) archived_from_url = views.get_archived_from_url(registered_node, file_node) view_url = self.project.web_url_for('addon_view_or_download_file', provider=file_node.provider, path=file_node.copied_from._id) assert_true(archived_from_url) assert_urls_equal(archived_from_url, view_url) @mock.patch('website.archiver.tasks.archive') def test_archived_from_url_without_copied_from(self, mock_archive): file_node = self.get_test_file() registered_node = self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) archived_from_url = views.get_archived_from_url(registered_node, file_node) assert_false(archived_from_url) @mock.patch('website.archiver.tasks.archive') def test_copied_from_id_trashed(self, mock_archive): file_node = self.get_test_file() second_file_node = self.get_second_test_file() file_node.copied_from = second_file_node self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) trashed_node = second_file_node.delete() assert_false(trashed_node.copied_from)
class TestS3ViewsConfig(OsfTestCase): def setUp(self): super(TestS3ViewsConfig, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.auth = ('test', self.user.api_keys[0]._primary_key) self.project = ProjectFactory(creator=self.user) self.project.add_addon('s3', auth=self.consolidated_auth) self.project.creator.add_addon('s3') self.user_settings = self.user.get_addon('s3') self.user_settings.access_key = 'We-Will-Rock-You' self.user_settings.secret_key = 'Idontknowanyqueensongs' self.user_settings.save() self.node_settings = self.project.get_addon('s3') self.node_settings.bucket = 'Sheer-Heart-Attack' self.node_settings.user_settings = self.project.creator.get_addon('s3') self.node_settings.save() self.node_url = '/api/v1/project/{0}/'.format(self.project._id) @mock.patch('website.addons.s3.views.config.does_bucket_exist') @mock.patch('website.addons.s3.views.config.adjust_cors') def test_s3_settings_no_bucket(self, mock_cors, mock_does_bucket_exist): mock_does_bucket_exist.return_value = False mock_cors.return_value = True url = self.project.api_url + 's3/settings/' rv = self.app.post_json(url, {}, expect_errors=True, auth=self.user.auth) assert_true('trouble' in rv.body) @mock.patch('website.addons.s3.views.config.does_bucket_exist') @mock.patch('website.addons.s3.views.config.adjust_cors') @mock.patch('website.addons.s3.utils.get_bucket_drop_down') def test_s3_set_bucket(self, mock_cors, mock_exist, mock_dropdown): mock_cors.return_value = True mock_exist.return_value = True mock_dropdown.return_value = ['mybucket'] url = self.project.api_url_for('s3_node_settings') self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=self.user.auth, ) self.project.reload() self.node_settings.reload() assert_equal(self.node_settings.bucket, 'hammertofall') assert_equal(self.project.logs[-1].action, 's3_bucket_linked') def test_s3_set_bucket_no_settings(self): user = AuthUserFactory() self.project.add_contributor(user, save=True) url = self.project.api_url + 's3/settings/' res = self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True ) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_no_auth(self): user = AuthUserFactory() user.add_addon('s3') self.project.add_contributor(user, save=True) url = self.project.api_url + 's3/settings/' res = self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True ) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_already_authed(self): user = AuthUserFactory() user.add_addon('s3') user_settings = user.get_addon('s3') user_settings.access_key = 'foo' user_settings.secret_key = 'bar' user_settings.save() self.project.add_contributor(user, save=True) url = self.project.api_url + 's3/settings/' res = self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True ) assert_equal(res.status_code, http.BAD_REQUEST) @mock.patch('website.addons.s3.api.S3Wrapper.from_addon') def test_s3_set_bucket_registered(self, mock_from_addon): mock_from_addon.return_value = create_mock_wrapper() registration = self.project.register_node( None, self.consolidated_auth, '', '' ) url = registration.api_url + 's3/settings/' res = self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=self.user.auth, expect_errors=True, ) assert_equal(res.status_code, http.BAD_REQUEST) @mock.patch('website.addons.s3.views.config.has_access') @mock.patch('website.addons.s3.views.config.create_osf_user') def test_user_settings(self, mock_user, mock_access): mock_access.return_value = True mock_user.return_value = ( 'osf-user-12345', { 'access_key_id': 'scout', 'secret_access_key': 'ssshhhhhhhhh' } ) url = '/api/v1/settings/s3/' self.app.post_json( url, { 'access_key': 'scout', 'secret_key': 'Atticus' }, auth=self.user.auth ) self.user_settings.reload() assert_equals(self.user_settings.access_key, 'scout') @mock.patch('website.addons.s3.model.AddonS3UserSettings.remove_iam_user') def test_s3_remove_user_settings(self, mock_access): mock_access.return_value = True self.user_settings.access_key = 'to-kill-a-mocking-bucket' self.user_settings.secret_key = 'itsasecret' self.user_settings.save() url = api_url_for('s3_remove_user_settings') self.app.delete(url, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, None) assert_equals(self.user_settings.secret_key, None) assert_equals(mock_access.call_count, 1) @mock.patch('website.addons.s3.model.AddonS3UserSettings.remove_iam_user') def test_s3_remove_user_settings_none(self, mock_access): self.user_settings.access_key = None self.user_settings.secret_key = None self.user_settings.save() url = api_url_for('s3_remove_user_settings') self.app.delete(url, auth=self.user.auth) self.user_settings.reload() assert_equals(mock_access.call_count, 0) @mock.patch('website.addons.s3.views.config.has_access') def test_user_settings_no_auth(self, mock_access): mock_access.return_value = False url = '/api/v1/settings/s3/' rv = self.app.post_json(url, {}, auth=self.user.auth, expect_errors=True) assert_equals(rv.status_int, http.BAD_REQUEST) @mock.patch('website.addons.s3.utils.get_bucket_drop_down') @mock.patch('website.addons.s3.views.config.has_access') @mock.patch('website.addons.s3.views.config.create_osf_user') def test_node_settings_no_user_settings(self, mock_user, mock_access, mock_dropdown): self.node_settings.user_settings = None self.node_settings.save() url = self.node_url + 's3/authorize/' mock_access.return_value = True mock_user.return_value = ( 'osf-user-12345', { 'access_key_id': 'scout', 'secret_access_key': 'ssshhhhhhhhh' } ) mock_dropdown.return_value = ['mybucket'] self.app.post_json(url, {'access_key': 'scout', 'secret_key': 'ssshhhhhhhhh'}, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, 'scout') @mock.patch('website.addons.s3.utils.get_bucket_drop_down') def test_node_settings_no_user_settings_ui(self, mock_dropdown): mock_dropdown.return_value = ['mybucket'] self.node_settings.user_settings.access_key = None self.node_settings.user_settings = None self.node_settings.save() url = self.project.url + 'settings/' rv = self.app.get(url, auth=self.user.auth) assert_true('<label for="s3Addon">Access Key</label>' in rv.body) @mock.patch('website.addons.s3.utils.get_bucket_list') def test_s3_bucket_list(self, mock_bucket_list): fake_buckets = [ MockS3Bucket(name=fake.domain_word()) for i in range(10) ] mock_bucket_list.return_value = fake_buckets url = self.node_settings.owner.api_url_for('s3_bucket_list') ret = self.app.get(url, auth=self.user.auth) assert_equals(ret.json, {'buckets': [bucket.name for bucket in fake_buckets]}) def test_s3_remove_node_settings_owner(self): url = self.node_settings.owner.api_url_for('s3_remove_node_settings') ret = self.app.delete(url, auth=self.user.auth) assert_equal(ret.json['has_bucket'], False) assert_equal(ret.json['node_has_auth'], False) def test_s3_remove_node_settings_unauthorized(self): url = self.node_settings.owner.api_url_for('s3_remove_node_settings') ret = self.app.delete(url, auth=None, expect_errors=True) assert_equal(ret.status_code, 401) def test_s3_get_node_settings_owner(self): url = self.node_settings.owner.api_url_for('s3_get_node_settings') res = self.app.get(url, auth=self.user.auth) expected_bucket = self.node_settings.bucket expected_node_has_auth = True expected_user_is_owner = True result = res.json['result'] assert_equal(result['bucket'], expected_bucket) assert_equal(result['node_has_auth'], expected_node_has_auth) assert_equal(result['user_is_owner'], expected_user_is_owner) def test_s3_get_node_settings_not_owner(self): url = self.node_settings.owner.api_url_for('s3_get_node_settings') non_owner = AuthUserFactory() self.project.add_contributor(non_owner, save=True, permissions=['write']) res = self.app.get(url, auth=non_owner.auth) expected_bucket = self.node_settings.bucket expected_node_has_auth = True expected_user_is_owner = False result = res.json['result'] assert_equal(result['bucket'], expected_bucket) assert_equal(result['node_has_auth'], expected_node_has_auth) assert_equal(result['user_is_owner'], expected_user_is_owner) def test_s3_get_node_settings_unauthorized(self): url = self.node_settings.owner.api_url_for('s3_get_node_settings') unauthorized = AuthUserFactory() ret = self.app.get(url, auth=unauthorized.auth, expect_errors=True) assert_equal(ret.status_code, 403) @mock.patch('website.addons.s3.views.config.add_s3_auth') def test_s3_authorize_node_valid(self, mock_add): mock_add.return_value = True url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth) assert_equal(res.json['node_has_auth'], True) def test_s3_authorize_node_invalid(self): url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) @mock.patch('website.addons.s3.views.config.add_s3_auth') def test_s3_authorize_node_malformed(self, mock_add): mock_add.return_value = False url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_equal(res.json['message'], 'Incorrect credentials') assert_equal(res.status_code, 400) @mock.patch('website.addons.s3.views.config.add_s3_auth') def test_s3_authorize_node_unauthorized(self, mock_add): mock_add.return_value = True url = self.project.api_url_for('s3_authorize_node') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } unauthorized = AuthUserFactory() res = self.app.post_json(url, cred, auth=unauthorized.auth, expect_errors=True) assert_equal(res.status_code, 403) @mock.patch('website.addons.s3.views.config.add_s3_auth') def test_s3_authorize_user_valid(self, mock_add): mock_add.return_value = True url = self.project.api_url_for('s3_authorize_user') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth) assert_equal(res.json, {}) def test_s3_authorize_user_invalid(self): url = self.project.api_url_for('s3_authorize_user') cred = { 'access_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) @mock.patch('website.addons.s3.views.config.add_s3_auth') def test_s3_authorize_user_malformed(self, mock_add): mock_add.return_value = False url = self.project.api_url_for('s3_authorize_user') cred = { 'access_key': fake.password(), 'secret_key': fake.password(), } res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_equal(res.json['message'], 'Incorrect credentials') assert_equal(res.status_code, 400) def test_s3_node_import_auth_authorized(self): url = self.project.api_url_for('s3_node_import_auth') self.node_settings.deauthorize(auth=None, save=True) res = self.app.post(url, auth=self.user.auth) assert_equal(res.json['node_has_auth'], True) assert_equal(res.json['user_is_owner'], True) def test_s3_node_import_auth_unauthorized(self): url = self.project.api_url_for('s3_node_import_auth') self.node_settings.deauthorize(auth=None, save=True) unauthorized = AuthUserFactory() res = self.app.post(url, auth=unauthorized.auth, expect_errors=True) assert_equal(res.status_code, 403)
class TestDropboxNodeSettingsModel(OsfTestCase): def setUp(self): super(TestDropboxNodeSettingsModel, self).setUp() self.user = UserFactory() self.user.add_addon("dropbox") self.user.save() self.user_settings = self.user.get_addon("dropbox") self.project = ProjectFactory() self.node_settings = DropboxNodeSettingsFactory(user_settings=self.user_settings, owner=self.project) def test_complete_true(self): self.node_settings.user_settings.access_token = "seems legit" assert_true(self.node_settings.has_auth) assert_true(self.node_settings.complete) def test_complete_false(self): self.node_settings.user_settings.access_token = "seems legit" self.node_settings.folder = None assert_true(self.node_settings.has_auth) assert_false(self.node_settings.complete) def test_complete_auth_false(self): self.node_settings.user_settings = None assert_false(self.node_settings.has_auth) assert_false(self.node_settings.complete) def test_fields(self): node_settings = DropboxNodeSettings(user_settings=self.user_settings) node_settings.save() assert_true(node_settings.user_settings) assert_equal(node_settings.user_settings.owner, self.user) assert_true(hasattr(node_settings, "folder")) assert_true(hasattr(node_settings, "registration_data")) def test_folder_defaults_to_none(self): node_settings = DropboxNodeSettings(user_settings=self.user_settings) node_settings.save() assert_is_none(node_settings.folder) def test_has_auth(self): settings = DropboxNodeSettings(user_settings=self.user_settings) settings.save() assert_false(settings.has_auth) settings.user_settings.access_token = "123abc" settings.user_settings.save() assert_true(settings.has_auth) def test_to_json(self): settings = self.node_settings user = UserFactory() result = settings.to_json(user) assert_equal(result["addon_short_name"], "dropbox") def test_delete(self): assert_true(self.node_settings.user_settings) assert_true(self.node_settings.folder) old_logs = self.project.logs self.node_settings.delete() self.node_settings.save() assert_is(self.node_settings.user_settings, None) assert_is(self.node_settings.folder, None) assert_true(self.node_settings.deleted) assert_equal(self.project.logs, old_logs) def test_deauthorize(self): assert_true(self.node_settings.user_settings) assert_true(self.node_settings.folder) self.node_settings.deauthorize(auth=Auth(self.user)) self.node_settings.save() assert_is(self.node_settings.user_settings, None) assert_is(self.node_settings.folder, None) last_log = self.project.logs[-1] assert_equal(last_log.action, "dropbox_node_deauthorized") params = last_log.params assert_in("node", params) assert_in("project", params) assert_in("folder", params) def test_set_folder(self): folder_name = "queen/freddie" self.node_settings.set_folder(folder_name, auth=Auth(self.user)) self.node_settings.save() # Folder was set assert_equal(self.node_settings.folder, folder_name) # Log was saved last_log = self.project.logs[-1] assert_equal(last_log.action, "dropbox_folder_selected") def test_set_user_auth(self): node_settings = DropboxNodeSettingsFactory() user_settings = DropboxUserSettingsFactory() node_settings.set_user_auth(user_settings) node_settings.save() assert_true(node_settings.has_auth) assert_equal(node_settings.user_settings, user_settings) # A log was saved last_log = node_settings.owner.logs[-1] assert_equal(last_log.action, "dropbox_node_authorized") log_params = last_log.params assert_equal(log_params["folder"], node_settings.folder) assert_equal(log_params["node"], node_settings.owner._primary_key) assert_equal(last_log.user, user_settings.owner) def test_serialize_credentials(self): self.user_settings.access_token = "secret" self.user_settings.save() credentials = self.node_settings.serialize_waterbutler_credentials() expected = {"token": self.node_settings.user_settings.access_token} assert_equal(credentials, expected) def test_serialize_credentials_not_authorized(self): self.node_settings.user_settings = None self.node_settings.save() with assert_raises(exceptions.AddonError): self.node_settings.serialize_waterbutler_credentials() def test_serialize_settings(self): settings = self.node_settings.serialize_waterbutler_settings() expected = {"folder": self.node_settings.folder} assert_equal(settings, expected) def test_serialize_settings_not_configured(self): self.node_settings.folder = None self.node_settings.save() with assert_raises(exceptions.AddonError): self.node_settings.serialize_waterbutler_settings() def test_create_log(self): action = "file_added" path = "pizza.nii" self.node_settings.folder = "/SomeOddPath" self.node_settings.save() nlog = len(self.project.logs) self.node_settings.create_waterbutler_log(auth=Auth(user=self.user), action=action, metadata={"path": path}) self.project.reload() assert_equal(len(self.project.logs), nlog + 1) assert_equal(self.project.logs[-1].action, "dropbox_{0}".format(action)) assert_equal(self.project.logs[-1].params["path"], path) @mock.patch("website.archiver.tasks.archive") def test_does_not_get_copied_to_registrations(self, mock_archive): registration = self.project.register_node( schema=None, auth=Auth(user=self.project.creator), template="Template1", data="hodor" ) assert_false(registration.has_addon("dropbox"))
class TestS3ViewsConfig(OsfTestCase): def setUp(self): super(TestS3ViewsConfig, self).setUp() self.patcher = mock.patch("website.addons.s3.model.AddonS3UserSettings.is_valid", new=True) self.patcher.start() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.auth = self.user.auth self.project = ProjectFactory(creator=self.user) self.project.add_addon("s3", auth=self.consolidated_auth) self.project.creator.add_addon("s3") self.user_settings = self.user.get_addon("s3") self.user_settings.access_key = "We-Will-Rock-You" self.user_settings.secret_key = "Idontknowanyqueensongs" self.user_settings.save() self.node_settings = self.project.get_addon("s3") self.node_settings.bucket = "Sheer-Heart-Attack" self.node_settings.user_settings = self.project.creator.get_addon("s3") self.node_settings.save() self.node_url = "/api/v1/project/{0}/".format(self.project._id) def tearDown(self): super(TestS3ViewsConfig, self).tearDown() self.patcher.stop() def test_s3_settings_input_empty_keys(self): url = self.project.api_url_for("s3_post_user_settings") rv = self.app.post_json(url, {"access_key": "", "secret_key": ""}, auth=self.user.auth, expect_errors=True) assert_equals(rv.status_int, http.BAD_REQUEST) assert_in("All the fields above are required.", rv.body) def test_s3_settings_input_empty_access_key(self): url = self.project.api_url_for("s3_post_user_settings") rv = self.app.post_json( url, {"access_key": "", "secret_key": "Non-empty-secret-key"}, auth=self.user.auth, expect_errors=True ) assert_equals(rv.status_int, http.BAD_REQUEST) assert_in("All the fields above are required.", rv.body) def test_s3_settings_input_empty_secret_key(self): url = self.project.api_url_for("s3_post_user_settings") rv = self.app.post_json( url, {"access_key": "Non-empty-access-key", "secret_key": ""}, auth=self.user.auth, expect_errors=True ) assert_equals(rv.status_int, http.BAD_REQUEST) assert_in("All the fields above are required.", rv.body) def test_s3_settings_no_bucket(self): rv = self.app.post_json( self.project.api_url_for("s3_post_node_settings"), {}, expect_errors=True, auth=self.user.auth ) assert_in("trouble", rv.body) @mock.patch("website.addons.s3.views.config.utils.bucket_exists") def test_s3_set_bucket(self, mock_exists): mock_exists.return_value = True url = self.project.api_url_for("s3_post_node_settings") self.app.post_json(url, {"s3_bucket": "hammertofall"}, auth=self.user.auth) self.project.reload() self.node_settings.reload() assert_equal(self.node_settings.bucket, "hammertofall") assert_equal(self.project.logs[-1].action, "s3_bucket_linked") def test_s3_set_bucket_no_settings(self): user = AuthUserFactory() self.project.add_contributor(user, save=True) url = self.project.api_url_for("s3_post_node_settings") res = self.app.post_json(url, {"s3_bucket": "hammertofall"}, auth=user.auth, expect_errors=True) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_no_auth(self): user = AuthUserFactory() user.add_addon("s3") self.project.add_contributor(user, save=True) url = self.project.api_url_for("s3_post_node_settings") res = self.app.post_json(url, {"s3_bucket": "hammertofall"}, auth=user.auth, expect_errors=True) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_already_authed(self): user = AuthUserFactory() user.add_addon("s3") user_settings = user.get_addon("s3") user_settings.access_key = "foo" user_settings.secret_key = "bar" user_settings.save() self.project.add_contributor(user, save=True) url = self.project.api_url_for("s3_post_node_settings") res = self.app.post_json(url, {"s3_bucket": "hammertofall"}, auth=user.auth, expect_errors=True) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_registered(self): registration = self.project.register_node(get_default_metaschema(), self.consolidated_auth, "", "") url = registration.api_url_for("s3_post_node_settings") res = self.app.post_json(url, {"s3_bucket": "hammertofall"}, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, http.BAD_REQUEST) @mock.patch("website.addons.s3.views.config.utils.can_list", return_value=True) def test_user_settings(self, _): url = self.project.api_url_for("s3_post_user_settings") self.app.post_json( url, {"access_key": "Steven Hawking", "secret_key": "Atticus Fitch killing mocking"}, auth=self.user.auth ) self.user_settings.reload() assert_equals(self.user_settings.access_key, "Steven Hawking") assert_equals(self.user_settings.secret_key, "Atticus Fitch killing mocking") @mock.patch("website.addons.s3.views.config.utils.can_list", return_value=True) def test_user_settings_when_user_does_not_have_addon(self, _): user = AuthUserFactory() url = self.project.api_url_for("s3_post_user_settings") self.app.post_json(url, {"access_key": "ABCDEFG", "secret_key": "We are the champions"}, auth=user.auth) user.reload() user_settings = user.get_addon("s3") assert_equals(user_settings.access_key, "ABCDEFG") assert_equals(user_settings.secret_key, "We are the champions") def test_s3_remove_user_settings(self): self.user_settings.access_key = "to-kill-a-mocking-bucket" self.user_settings.secret_key = "itsasecret" self.user_settings.save() url = api_url_for("s3_delete_user_settings") self.app.delete(url, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, None) assert_equals(self.user_settings.secret_key, None) # Last log has correct action and user self.project.reload() last_project_log = self.project.logs[-1] assert_equal(last_project_log.action, "s3_node_deauthorized") assert_equal(last_project_log.user, self.user) def test_s3_remove_user_settings_none(self): self.user_settings.access_key = None self.user_settings.secret_key = None self.user_settings.save() url = api_url_for("s3_delete_user_settings") self.app.delete(url, auth=self.user.auth) self.user_settings.reload() @mock.patch("website.addons.s3.views.config.utils.can_list", return_value=False) def test_user_settings_cant_list(self, mock_can_list): url = api_url_for("s3_post_user_settings") rv = self.app.post_json( url, {"access_key": "aldkjf", "secret_key": "las"}, auth=self.user.auth, expect_errors=True ) assert_equals(rv.status_int, http.BAD_REQUEST) assert_in("Unable to list buckets.", rv.body) @mock.patch("website.addons.s3.views.config.utils.can_list", return_value=True) def test_node_settings_no_user_settings(self, mock_can_list): self.node_settings.user_settings = None self.node_settings.save() url = self.project.api_url_for("s3_authorize_node") self.app.post_json(url, {"access_key": "scout", "secret_key": "ssshhhhhhhhh"}, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, "scout") @mock.patch("website.addons.s3.views.config.utils.get_bucket_names") def test_s3_bucket_list(self, mock_bucket_list): fake_buckets = [] for _ in range(10): fake_bucket = mock.Mock() fake_bucket.name = fake.domain_word() fake_bucket.append(fake_bucket) mock_bucket_list.return_value = fake_buckets url = self.node_settings.owner.api_url_for("s3_get_bucket_list") ret = self.app.get(url, auth=self.user.auth) assert_equals(ret.json, {"buckets": [bucket.name for bucket in fake_buckets]}) def test_s3_remove_node_settings_owner(self): url = self.node_settings.owner.api_url_for("s3_delete_node_settings") ret = self.app.delete(url, auth=self.user.auth) assert_equal(ret.json["has_bucket"], False) assert_equal(ret.json["node_has_auth"], False) def test_s3_remove_node_settings_unauthorized(self): url = self.node_settings.owner.api_url_for("s3_delete_node_settings") ret = self.app.delete(url, auth=None, expect_errors=True) assert_equal(ret.status_code, 401) def test_s3_get_node_settings_owner(self): url = self.node_settings.owner.api_url_for("s3_get_node_settings") res = self.app.get(url, auth=self.user.auth) result = res.json["result"] assert_equal(result["node_has_auth"], True) assert_equal(result["user_is_owner"], True) assert_equal(result["bucket"], self.node_settings.bucket) def test_s3_get_node_settings_not_owner(self): url = self.node_settings.owner.api_url_for("s3_get_node_settings") non_owner = AuthUserFactory() self.project.add_contributor(non_owner, save=True, permissions=["write"]) res = self.app.get(url, auth=non_owner.auth) result = res.json["result"] assert_equal(result["bucket"], self.node_settings.bucket) assert_equal(result["node_has_auth"], True) assert_equal(result["user_is_owner"], False) def test_s3_get_node_settings_unauthorized(self): url = self.node_settings.owner.api_url_for("s3_get_node_settings") unauthorized = AuthUserFactory() ret = self.app.get(url, auth=unauthorized.auth, expect_errors=True) assert_equal(ret.status_code, 403) @mock.patch("website.addons.s3.views.config.utils.can_list", return_value=True) def test_s3_authorize_node_valid(self, _): url = self.project.api_url_for("s3_authorize_node") cred = {"access_key": fake.password(), "secret_key": fake.password()} res = self.app.post_json(url, cred, auth=self.user.auth) assert_equal(res.json["node_has_auth"], True) def test_s3_authorize_node_malformed(self): url = self.project.api_url_for("s3_authorize_node") cred = {"access_key": fake.password()} res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) @mock.patch("website.addons.s3.views.config.utils.can_list", return_value=False) def test_s3_authorize_node_invalid(self, _): url = self.project.api_url_for("s3_authorize_node") cred = {"access_key": fake.password(), "secret_key": fake.password()} res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_in("Unable to list buckets", res.json["message"]) assert_equal(res.status_code, 400) def test_s3_authorize_node_unauthorized(self): url = self.project.api_url_for("s3_authorize_node") cred = {"access_key": fake.password(), "secret_key": fake.password()} unauthorized = AuthUserFactory() res = self.app.post_json(url, cred, auth=unauthorized.auth, expect_errors=True) assert_equal(res.status_code, 403) @mock.patch("website.addons.s3.views.config.utils.can_list", return_value=True) def test_s3_authorize_user_valid(self, _): url = self.project.api_url_for("s3_authorize_node") cred = {"access_key": fake.password(), "secret_key": fake.password()} res = self.app.post_json(url, cred, auth=self.user.auth) assert_equal(res.status_code, 200) def test_s3_authorize_user_malformed(self): url = self.project.api_url_for("s3_authorize_node") cred = {"access_key": fake.password()} res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) @mock.patch("website.addons.s3.views.config.utils.can_list", return_value=False) def test_s3_authorize_user_invalid(self, _): url = self.project.api_url_for("s3_authorize_node") cred = {"access_key": fake.password(), "secret_key": fake.password()} res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_in("Unable to list buckets", res.json["message"]) assert_equal(res.status_code, 400) def test_s3_authorize_input_empty_keys(self): url = self.project.api_url_for("s3_authorize_node") cred = {"access_key": "", "secret_key": ""} res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_in("All the fields above are required", res.json["message"]) assert_equal(res.status_code, 400) def test_s3_authorize_input_empty_access_key(self): url = self.project.api_url_for("s3_authorize_node") cred = {"access_key": "", "secret_key": "Non-empty-secret-key"} res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_in("All the fields above are required", res.json["message"]) assert_equal(res.status_code, 400) def test_s3_authorize_input_empty_secret_key(self): url = self.project.api_url_for("s3_authorize_node") cred = {"access_key": "Non-empty-access-key", "secret_key": ""} res = self.app.post_json(url, cred, auth=self.user.auth, expect_errors=True) assert_in("All the fields above are required", res.json["message"]) assert_equal(res.status_code, 400) @mock.patch("website.addons.s3.views.config.utils.can_list", return_value=True) def test_s3_node_import_auth_authorized(self, _): url = self.project.api_url_for("s3_node_import_auth") self.node_settings.deauthorize(auth=None, save=True) res = self.app.post(url, auth=self.user.auth) assert_equal(res.json["node_has_auth"], True) assert_equal(res.json["user_is_owner"], True) def test_s3_node_import_auth_unauthorized(self): url = self.project.api_url_for("s3_node_import_auth") self.node_settings.deauthorize(auth=None, save=True) unauthorized = AuthUserFactory() res = self.app.post(url, auth=unauthorized.auth, expect_errors=True) assert_equal(res.status_code, 403)
class TestAddonFileViews(OsfTestCase): @classmethod def setUpClass(cls): super(TestAddonFileViews, cls).setUpClass() PROVIDER_MAP['github'] = [TestFolder, TestFile, TestFileNode] TestFileNode.provider = 'github' def setUp(self): super(TestAddonFileViews, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.user.add_addon('github') self.project.add_addon('github', auth=Auth(self.user)) self.user_addon = self.user.get_addon('github') self.node_addon = self.project.get_addon('github') self.oauth = GitHubAccountFactory() self.oauth.save() self.user.external_accounts.append(self.oauth) self.user.save() self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth self.node_addon.repo = 'Truth' self.node_addon.user = '******' self.node_addon.save() @classmethod def tearDownClass(cls): super(TestAddonFileViews, cls).tearDownClass() PROVIDER_MAP['github'] = [ models.GithubFolder, models.GithubFile, models.GithubFileNode ] del PROVIDER_MAP['test_addons'] TrashedFileNode.remove() def get_test_file(self): version = models.FileVersion(identifier='1') version.save() versions = [version] ret = TestFile(name='Test', node=self.project, path='/test/Test', materialized_path='/test/Test', versions=versions) ret.save() return ret def get_second_test_file(self): version = models.FileVersion(identifier='1') version.save() ret = TestFile(name='Test2', node=self.project, path='/test/Test2', materialized_path='/test/Test2', versions=[version]) ret.save() return ret def get_mako_return(self): ret = serialize_node(self.project, Auth(self.user), primary=True) ret.update({ 'error': '', 'provider': '', 'file_path': '', 'sharejs_uuid': '', 'private': '', 'urls': { 'files': '', 'render': '', 'sharejs': '', 'mfr': '', 'gravatar': '', 'external': '', 'archived_from': '', }, 'size': '', 'extra': '', 'file_name': '', 'materialized_path': '', 'file_id': '', }) ret.update(rubeus.collect_addon_assets(self.project)) return ret def test_redirects_to_guid(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github'), auth=self.user.auth) assert_equals(resp.status_code, 302) assert_equals(resp.location, 'http://*****:*****@mock.patch('website.addons.base.views.addon_view_file') def test_action_view_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/?action=view'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) @mock.patch('website.addons.base.views.addon_view_file') def test_no_action_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) def test_download_create_guid(self): file_node = self.get_test_file() assert_is(file_node.get_guid(), None) self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github', ), auth=self.user.auth) assert_true(file_node.get_guid()) def test_view_file_does_not_delete_file_when_requesting_invalid_version( self): with mock.patch( 'website.addons.github.model.GitHubNodeSettings.is_private', new_callable=mock.PropertyMock) as mock_is_private: mock_is_private.return_value = False file_node = self.get_test_file() assert_is(file_node.get_guid(), None) url = self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github', ) # First view generated GUID self.app.get(url, auth=self.user.auth) self.app.get(url + '?version=invalid', auth=self.user.auth, expect_errors=True) assert_is_not_none(StoredFileNode.load(file_node._id)) assert_is_none(TrashedFileNode.load(file_node._id)) def test_unauthorized_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download'), auth=self.user.auth, expect_errors=True) assert_equals(resp.status_code, 401) def test_nonstorage_addons_raise(self): resp = self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path='sillywiki', provider='wiki', action='download'), auth=self.user.auth, expect_errors=True) assert_equals(resp.status_code, 400) def test_head_returns_url(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head('/{}/'.format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) assert_urls_equal( location.url, file_node.generate_waterbutler_url(direct=None, version=None)) def test_head_returns_url_with_version(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head('/{}/?revision=1&foo=bar'.format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) # Note: version is added but us but all other url params are added as well assert_urls_equal( location.url, file_node.generate_waterbutler_url(direct=None, revision=1, version=None, foo='bar')) def test_nonexistent_addons_raise(self): path = 'cloudfiles' self.project.delete_addon('github', Auth(self.user)) self.project.save() resp = self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download'), auth=self.user.auth, expect_errors=True) assert_equals(resp.status_code, 400) def test_unauth_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download'), auth=self.user.auth, expect_errors=True) assert_equals(resp.status_code, 401) def test_delete_action_creates_trashed_file_node(self): file_node = self.get_test_file() payload = { 'provider': file_node.provider, 'metadata': { 'path': '/test/Test', 'materialized': '/test/Test' } } views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload) assert_false(StoredFileNode.load(file_node._id)) assert_true(TrashedFileNode.load(file_node._id)) def test_delete_action_for_folder_deletes_subfolders_and_creates_trashed_file_nodes( self): file_node = self.get_test_file() subfolder = TestFolder(name='folder', node=self.project, path='/test/folder/', materialized_path='/test/folder/', versions=[]) subfolder.save() payload = { 'provider': file_node.provider, 'metadata': { 'path': '/test/', 'materialized': '/test/' } } views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload) assert_false(StoredFileNode.load(file_node._id)) assert_true(TrashedFileNode.load(file_node._id)) assert_false(StoredFileNode.load(subfolder._id)) @mock.patch('website.archiver.tasks.archive') def test_archived_from_url(self, mock_archive): file_node = self.get_test_file() second_file_node = self.get_second_test_file() file_node.copied_from = second_file_node registered_node = self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) archived_from_url = views.get_archived_from_url( registered_node, file_node) view_url = self.project.web_url_for('addon_view_or_download_file', provider=file_node.provider, path=file_node.copied_from._id) assert_true(archived_from_url) assert_urls_equal(archived_from_url, view_url) @mock.patch('website.archiver.tasks.archive') def test_archived_from_url_without_copied_from(self, mock_archive): file_node = self.get_test_file() registered_node = self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) archived_from_url = views.get_archived_from_url( registered_node, file_node) assert_false(archived_from_url) @mock.patch('website.archiver.tasks.archive') def test_copied_from_id_trashed(self, mock_archive): file_node = self.get_test_file() second_file_node = self.get_second_test_file() file_node.copied_from = second_file_node self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) trashed_node = second_file_node.delete() assert_false(trashed_node.copied_from)
class TestS3ViewsConfig(OsfTestCase): def setUp(self): super(TestS3ViewsConfig, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.auth = ('test', self.user.api_keys[0]._primary_key) self.project = ProjectFactory(creator=self.user) self.project.add_addon('s3', auth=self.consolidated_auth) self.project.creator.add_addon('s3') self.user_settings = self.user.get_addon('s3') self.user_settings.access_key = 'We-Will-Rock-You' self.user_settings.secret_key = 'Idontknowanyqueensongs' self.user_settings.save() self.node_settings = self.project.get_addon('s3') self.node_settings.bucket = 'Sheer-Heart-Attack' self.node_settings.user_settings = self.project.creator.get_addon('s3') self.node_settings.save() self.node_url = '/api/v1/project/{0}/'.format(self.project._id) @mock.patch('website.addons.s3.views.config.does_bucket_exist') @mock.patch('website.addons.s3.views.config.adjust_cors') def test_s3_settings_no_bucket(self, mock_cors, mock_does_bucket_exist): mock_does_bucket_exist.return_value = False mock_cors.return_value = True url = self.project.api_url + 's3/settings/' rv = self.app.post_json(url, {}, expect_errors=True, auth=self.user.auth) assert_true('trouble' in rv.body) @mock.patch('website.addons.s3.views.config.does_bucket_exist') @mock.patch('website.addons.s3.views.config.adjust_cors') def test_s3_set_bucket(self, mock_cors, mock_exist): mock_cors.return_value = True mock_exist.return_value = True url = self.project.api_url + 's3/settings/' self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=self.user.auth, ) self.project.reload() self.node_settings.reload() assert_equal(self.node_settings.bucket, 'hammertofall') assert_equal(self.project.logs[-1].action, 's3_bucket_linked') def test_s3_set_bucket_no_settings(self): user = AuthUserFactory() self.project.add_contributor(user, save=True) url = self.project.api_url + 's3/settings/' res = self.app.post_json(url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_no_auth(self): user = AuthUserFactory() user.add_addon('s3') self.project.add_contributor(user, save=True) url = self.project.api_url + 's3/settings/' res = self.app.post_json(url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True) assert_equal(res.status_code, http.BAD_REQUEST) def test_s3_set_bucket_already_authed(self): user = AuthUserFactory() user.add_addon('s3') user_settings = user.get_addon('s3') user_settings.access_key = 'foo' user_settings.secret_key = 'bar' user_settings.save() self.project.add_contributor(user, save=True) url = self.project.api_url + 's3/settings/' res = self.app.post_json(url, {'s3_bucket': 'hammertofall'}, auth=user.auth, expect_errors=True) assert_equal(res.status_code, http.BAD_REQUEST) @mock.patch('website.addons.s3.api.S3Wrapper.from_addon') def test_s3_set_bucket_registered(self, mock_from_addon): mock_from_addon.return_value = create_mock_wrapper() registration = self.project.register_node(None, self.consolidated_auth, '', '') url = registration.api_url + 's3/settings/' res = self.app.post_json( url, {'s3_bucket': 'hammertofall'}, auth=self.user.auth, expect_errors=True, ) assert_equal(res.status_code, http.BAD_REQUEST) @mock.patch('website.addons.s3.views.config.has_access') @mock.patch('website.addons.s3.views.config.create_osf_user') def test_user_settings(self, mock_user, mock_access): mock_access.return_value = True mock_user.return_value = ('osf-user-12345', { 'access_key_id': 'scout', 'secret_access_key': 'ssshhhhhhhhh' }) url = '/api/v1/settings/s3/' self.app.post_json(url, { 'access_key': 'scout', 'secret_key': 'Atticus' }, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, 'scout') @mock.patch('website.addons.s3.model.AddonS3UserSettings.remove_iam_user') def test_s3_remove_user_settings(self, mock_access): mock_access.return_value = True self.user_settings.access_key = 'to-kill-a-mocking-bucket' self.user_settings.secret_key = 'itsasecret' self.user_settings.save() url = '/api/v1/settings/s3/' self.app.delete(url, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, None) assert_equals(self.user_settings.secret_key, None) assert_equals(mock_access.call_count, 1) @mock.patch('website.addons.s3.model.AddonS3UserSettings.remove_iam_user') def test_s3_remove_user_settings_none(self, mock_access): self.user_settings.access_key = None self.user_settings.secret_key = None self.user_settings.save() url = '/api/v1/settings/s3/' self.app.delete(url, auth=self.user.auth) self.user_settings.reload() assert_equals(mock_access.call_count, 0) @mock.patch('website.addons.s3.views.config.has_access') def test_user_settings_no_auth(self, mock_access): mock_access.return_value = False url = '/api/v1/settings/s3/' rv = self.app.post_json(url, {}, auth=self.user.auth, expect_errors=True) assert_equals(rv.status_int, http.BAD_REQUEST) @mock.patch('website.addons.s3.views.config.has_access') @mock.patch('website.addons.s3.views.config.create_osf_user') def test_node_settings_no_user_settings(self, mock_user, mock_access): self.node_settings.user_settings = None self.node_settings.save() url = self.node_url + 's3/authorize/' mock_access.return_value = True mock_user.return_value = ('osf-user-12345', { 'access_key_id': 'scout', 'secret_access_key': 'ssshhhhhhhhh' }) self.app.post_json(url, { 'access_key': 'scout', 'secret_key': 'ssshhhhhhhhh' }, auth=self.user.auth) self.user_settings.reload() assert_equals(self.user_settings.access_key, 'scout') def test_node_settings_no_user_settings_ui(self): self.node_settings.user_settings.access_key = None self.node_settings.user_settings = None self.node_settings.save() url = self.project.url + 'settings/' rv = self.app.get(url, auth=self.user.auth) assert_true('<label for="s3Addon">Access Key</label>' in rv.body) @mock.patch('website.addons.s3.model.get_bucket_drop_down') def test_node_settings_user_settings_ui(self, mock_dropdown): mock_dropdown.return_value = ['mybucket'] url = self.project.url + 'settings/' rv = self.app.get(url, auth=self.user.auth) assert_true('mybucket' in rv.body)
class TestFilesViews(OsfTestCase): def setUp(self): super(TestFilesViews, self).setUp() self.user = AuthUserFactory() self.auth = ('test', self.user.api_keys[0]._primary_key) self.consolidated_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.project.add_addon('osffiles', auth=self.consolidated_auth) self.node_settings = self.project.get_addon('osffiles') self.fid = 'firstfile' self._upload_file(self.fid, 'firstcontent') def _upload_file(self, name, content, **kwargs): url = self.project.api_url + 'osffiles/' res = self.app.post( url, upload_files=[ ('file', name, content), ], auth=self.auth, **kwargs ) self.project.reload() return res def test_download_file(self): url = self.project.uploads[0].download_url(self.project) res = self.app.get(url, auth=self.user.auth).maybe_follow() assert_equal(res.body, 'firstcontent') def test_download_file_by_version_with_bad_version_value(self): url = self.project.web_url_for('download_file_by_version', fid=self.fid, vid='bad' ) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_in('Invalid version', res.body) def test_download_file_by_version_with_nonexistent_file(self): url = self.project.web_url_for( 'download_file_by_version', fid='notfound', vid=0 ) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) def test_download_file_by_version_with_bad_version_number(self): url = self.project.web_url_for( 'download_file_by_version', fid=self.fid, vid=9999 ) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) def test_download_file_by_version_with_negative_version_number(self): url = self.project.web_url_for( 'download_file_by_version', fid=self.fid, vid=-1 ) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) def test_upload_file(self): node_addon = self.project.get_addon('osffiles') res = self._upload_file( 'newfile', 'a' * (node_addon.config.max_file_size) ) self.project.reload() assert_equal( self.project.logs[-1].action, 'file_added' ) assert_equal(res.status_code, 201) assert_true(isinstance(res.json, dict), 'return value is a dict') assert_equal(res.json['name'], 'newfile') assert_in('newfile', self.project.files_current) def test_upload_file_unicode_name(self): node_addon = self.project.get_addon('osffiles') res = self._upload_file( '_néwfile', 'a' * (node_addon.config.max_file_size) ) self.project.reload() assert_equal( self.project.logs[-1].action, 'file_added' ) assert_equal(res.status_code, 201) assert_true(isinstance(res.json, dict), 'return value is a dict') assert_equal(res.json['name'], '_newfile') assert_in('_newfile', self.project.files_current) def test_upload_file_too_large(self): node_addon = self.project.get_addon('osffiles') res = self._upload_file( 'newfile', 'a' * (node_addon.config.max_file_size + 1), expect_errors=True, ) self.project.reload() assert_equal(res.status_code, 400) assert_not_in('newfile', self.project.files_current) def test_file_info(self): # Upload a new version of firstfile self._upload_file(self.fid, 'secondcontent') url = self.project.api_url_for('file_info', fid=self.project.uploads[0].filename) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) file_obj = self.project.get_file_object(self.fid, version=1) data = res.json assert_equal(data['file_name'], self.fid) assert_equal(data['registered'], self.project.is_registration) assert_equal(len(data['versions']), 2) assert_equal(data['urls']['files'], self.project.web_url_for('collect_file_trees')) assert_equal(data['urls']['latest']['download'], file_obj.download_url(self.project)) assert_equal(data['urls']['api'], file_obj.api_url(self.project)) version = res.json['versions'][0] assert_equal(version['file_name'], self.fid) assert_equal(version['version_number'], 2) assert_equal(version['modified_date'], file_obj.date_uploaded.strftime('%Y/%m/%d %I:%M %p')) assert_in('downloads', version) assert_equal(version['committer_name'], file_obj.uploader.fullname) assert_equal(version['committer_url'], file_obj.uploader.url) def test_file_info_with_anonymous_link(self): link = PrivateLinkFactory(anonymous=True) link.nodes.append(self.project) link.save() self._upload_file('firstfile', 'secondcontent') url = self.project.api_url_for( 'file_info', fid=self.project.uploads[0].filename ) res = self.app.get(url, {'view_only': link.key}) assert_not_in(self.user.fullname, res.body) assert_not_in(self.user._id, res.body) def test_delete_file(self): url = self.project.api_url_for('delete_file', fid=self.fid) res = self.app.delete(url, auth=self.auth).maybe_follow() assert_equal(res.status_code, 200) self.project.reload() assert_not_in('firstfile', self.project.files_current) def test_delete_file_returns_404_when_file_is_already_deleted(self): self.project.remove_file(Auth(self.project.creator), self.fid) url = self.project.api_url_for('delete_file', fid=self.fid) res = self.app.delete_json(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) def test_file_urls(self): url = self.project.api_url + 'osffiles/hgrid/' res = self.app.get(url, auth=self.auth).maybe_follow() assert_equal(len(res.json), 1) for url in ['view', 'download', 'delete']: assert_in( self.project._id, res.json[0]['urls'][url] ) def test_file_urls_fork(self): fork = self.project.fork_node(auth=Auth(user=self.user)) url = fork.api_url + 'osffiles/hgrid/' res = self.app.get(url, auth=self.auth).maybe_follow() assert_equal(len(res.json), 1) for url in ['view', 'download', 'delete']: assert_in( fork._id, res.json[0]['urls'][url] ) def test_file_urls_registration(self): registration = self.project.register_node( None, Auth(user=self.user), '', '' ) url = registration.api_url + 'osffiles/hgrid/' res = self.app.get(url, auth=self.auth).maybe_follow() assert_equal(len(res.json), 1) for url in ['view', 'download', 'delete']: assert_in( registration._id, res.json[0]['urls'][url] ) def test_view_creates_guid(self): guid_fid = 'unique' guid_content = 'snowflake' self._upload_file(guid_fid, guid_content) node_file = NodeFile.load(self.project.files_current[guid_fid]) guid_count = OsfGuidFile.find().count() # View file for the first time url = node_file.url(self.project) res = self.app.get( url, auth=self.user.auth, ).follow( auth=self.user.auth, ) guid = OsfGuidFile.find_one( Q('node', 'eq', self.project) & Q('name', 'eq', guid_fid) ) # GUID count has been incremented by one assert_equal( OsfGuidFile.find().count(), guid_count + 1 ) # Client has been redirected to GUID assert_equal( res.request.path.strip('/'), guid._id, ) # View file for the second time self.app.get( url, auth=self.user.auth, ).follow( auth=self.user.auth, ) # GUID count has not been incremented assert_equal( OsfGuidFile.find().count(), guid_count + 1 ) def test_guid_url_returns_404(self): f = NodeFile() f.save() url = '/{}/'.format(f._id) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 404) def test_sees_delete_button_if_can_write(self): url = self.project.uploads[0].url(self.project) res = self.app.get( url, auth=self.user.auth, ).maybe_follow( auth=self.user.auth, ) assert_in('Download', res) assert_in('Delete', res) def test_does_not_see_delete_button_if_cannot_write(self): self.project.is_public = True self.project.save() user2 = AuthUserFactory() url = self.project.uploads[0].url(self.project) res = self.app.get( url, auth=user2.auth, ).maybe_follow( auth=user2.auth, ) assert_in('Download', res) assert_not_in('Delete', res)
class TestCallbacks(OsfTestCase): def setUp(self): super(TestCallbacks, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.auth = ('test', self.user.api_keys[0]._primary_key) self.project = ProjectFactory(creator=self.user) self.non_authenticator = AuthUserFactory() self.project.add_contributor( contributor=self.non_authenticator, auth=Auth(self.project.creator), ) self.project.add_addon('figshare', auth=self.consolidated_auth) self.project.creator.add_addon('figshare') self.node_settings = self.project.get_addon('figshare') self.user_settings = self.project.creator.get_addon('figshare') self.user_settings.oauth_access_token = 'legittoken' self.user_settings.oauth_access_token_secret = 'legittoken' self.user_settings.save() self.node_settings.user_settings = self.user_settings self.node_settings.figshare_id = '123456' self.node_settings.figshare_type = 'project' self.node_settings.figshare_title = 'singlefile' self.node_settings.save() def test_update_fields_project(self): num_logs = len(self.project.logs) # try updating fields newfields = {'type': 'project', 'id': '313131', 'name': 'A PROJECT'} self.node_settings.update_fields(newfields, self.project, Auth(self.project.creator)) #check for updated assert_equals(self.node_settings.figshare_id, '313131') assert_equals(self.node_settings.figshare_type, 'project') assert_equals(self.node_settings.figshare_title, 'A PROJECT') # check for log added assert_equals(len(self.project.logs), num_logs + 1) def test_update_fields_fileset(self): num_logs = len(self.project.logs) # try updating fields newfields = {'type': 'fileset', 'id': '313131', 'name': 'A FILESET'} self.node_settings.update_fields(newfields, self.project, Auth(self.project.creator)) #check for updated assert_equals(self.node_settings.figshare_id, '313131') assert_equals(self.node_settings.figshare_type, 'fileset') assert_equals(self.node_settings.figshare_title, 'A FILESET') # check for log added assert_equals(len(self.project.logs), num_logs + 1) def test_update_fields_some_missing(self): num_logs = len(self.project.logs) # try updating fields newfields = {'type': 'project', 'id': '313131', 'name': 'A PROJECT'} self.node_settings.update_fields(newfields, self.project, Auth(self.project.creator)) #check for updated assert_equals(self.node_settings.figshare_id, '313131') assert_equals(self.node_settings.figshare_title, 'A PROJECT') # check for log added assert_equals(len(self.project.logs), num_logs + 1) def test_update_fields_invalid(self): num_logs = len(self.project.logs) # try updating fields newfields = { 'adad': 131313, 'i1513': '313131', 'titladad': 'A PROJECT' } self.node_settings.update_fields(newfields, self.project, Auth(self.project.creator)) #check for updated assert_equals(self.node_settings.figshare_id, '123456') assert_equals(self.node_settings.figshare_type, 'project') assert_equals(self.node_settings.figshare_title, 'singlefile') # check for log added assert_equals(len(self.project.logs), num_logs) def test_api_url_no_user(self): self.node_settings.user_settings = None self.node_settings.save() assert_equal(self.node_settings.api_url, figshare_settings.API_URL) def test_api_url(self): assert_equal(self.node_settings.api_url, figshare_settings.API_OAUTH_URL) def test_before_register_linked_content(self): assert_false( self.node_settings.before_register(self.project, self.project.creator) is None) def test_before_register_no_linked_content(self): self.node_settings.figshare_id = None assert_true( self.node_settings.before_register(self.project, self.project.creator) is None) def test_before_remove_contributor_authenticator(self): message = self.node_settings.before_remove_contributor( self.project, self.project.creator) assert_true(message) def test_before_remove_contributor_not_authenticator(self): message = self.node_settings.before_remove_contributor( self.project, self.non_authenticator) assert_false(message) def test_after_remove_contributor_authenticator_not_self(self): auth = Auth(user=self.non_authenticator) msg = self.node_settings.after_remove_contributor( self.project, self.project.creator, auth) assert_in(self.project.project_or_component, msg) assert_equal(self.node_settings.user_settings, None) assert_in("You can re-authenticate", msg) def test_after_remove_contributor_authenticator_self(self): msg = self.node_settings.after_remove_contributor( self.project, self.project.creator, self.consolidated_auth) assert_in(self.project.title, msg) assert_equal(self.node_settings.user_settings, None) assert_not_in("You can re-authenticate", msg) def test_after_fork_authenticator(self): fork = ProjectFactory() clone, message = self.node_settings.after_fork( self.project, fork, self.project.creator, ) assert_equal( self.node_settings.user_settings, clone.user_settings, ) def test_after_fork_not_authenticator(self): fork = ProjectFactory() clone, message = self.node_settings.after_fork( self.project, fork, self.non_authenticator, ) assert_equal( clone.user_settings, None, ) def test_after_delete(self): self.project.remove_node(Auth(user=self.project.creator)) # Ensure that changes to node settings have been saved self.node_settings.reload() assert_true(self.node_settings.user_settings is None) assert_true(self.node_settings.figshare_id is None) assert_true(self.node_settings.figshare_type is None) assert_true(self.node_settings.figshare_title is None) def test_does_not_get_copied_to_registrations(self): registration = self.project.register_node( schema=None, auth=Auth(user=self.project.creator), template='Template1', data='hodor') assert_false(registration.has_addon('figshare'))
class TestFilesViews(OsfTestCase): def setUp(self): super(TestFilesViews, self).setUp() self.user = AuthUserFactory() self.auth = ('test', self.user.api_keys[0]._primary_key) self.consolidated_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.project.add_addon('osffiles', auth=self.consolidated_auth) self.node_settings = self.project.get_addon('osffiles') self.fid = 'firstfile' self._upload_file(self.fid, 'firstcontent') def _upload_file(self, name, content, **kwargs): url = self.project.api_url + 'osffiles/' res = self.app.post(url, upload_files=[ ('file', name, content), ], auth=self.auth, **kwargs) self.project.reload() return res def test_download_file(self): url = self.project.uploads[0].download_url(self.project) res = self.app.get(url, auth=self.user.auth).maybe_follow() assert_equal(res.body, 'firstcontent') def test_download_file_by_version_with_bad_version_value(self): url = self.project.web_url_for('download_file_by_version', fid=self.fid, vid='bad') res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_in('Invalid version', res.body) def test_download_file_by_version_with_nonexistent_file(self): url = self.project.web_url_for('download_file_by_version', fid='notfound', vid=0) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) def test_download_file_by_version_with_bad_version_number(self): url = self.project.web_url_for('download_file_by_version', fid=self.fid, vid=9999) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) def test_download_file_by_version_with_negative_version_number(self): url = self.project.web_url_for('download_file_by_version', fid=self.fid, vid=-1) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) def test_upload_file(self): node_addon = self.project.get_addon('osffiles') res = self._upload_file('newfile', 'a' * (node_addon.config.max_file_size)) self.project.reload() assert_equal(self.project.logs[-1].action, 'file_added') assert_equal(res.status_code, 201) assert_true(isinstance(res.json, dict), 'return value is a dict') assert_equal(res.json['name'], 'newfile') assert_in('newfile', self.project.files_current) def test_upload_file_unicode_name(self): node_addon = self.project.get_addon('osffiles') res = self._upload_file('_néwfile', 'a' * (node_addon.config.max_file_size)) self.project.reload() assert_equal(self.project.logs[-1].action, 'file_added') assert_equal(res.status_code, 201) assert_true(isinstance(res.json, dict), 'return value is a dict') assert_equal(res.json['name'], '_newfile') assert_in('_newfile', self.project.files_current) def test_upload_file_too_large(self): node_addon = self.project.get_addon('osffiles') res = self._upload_file( 'newfile', 'a' * (node_addon.config.max_file_size + 1), expect_errors=True, ) self.project.reload() assert_equal(res.status_code, 400) assert_not_in('newfile', self.project.files_current) def test_file_info(self): # Upload a new version of firstfile self._upload_file(self.fid, 'secondcontent') url = self.project.api_url_for('file_info', fid=self.project.uploads[0].filename) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) file_obj = self.project.get_file_object(self.fid, version=1) data = res.json assert_equal(data['file_name'], self.fid) assert_equal(data['registered'], self.project.is_registration) assert_equal(len(data['versions']), 2) assert_equal(data['urls']['files'], self.project.web_url_for('collect_file_trees')) assert_equal(data['urls']['latest']['download'], file_obj.download_url(self.project)) assert_equal(data['urls']['api'], file_obj.api_url(self.project)) version = res.json['versions'][0] assert_equal(version['file_name'], self.fid) assert_equal(version['version_number'], 2) assert_equal(version['modified_date'], file_obj.date_uploaded.strftime('%Y/%m/%d %I:%M %p')) assert_in('downloads', version) assert_equal(version['committer_name'], file_obj.uploader.fullname) assert_equal(version['committer_url'], file_obj.uploader.url) def test_file_info_with_anonymous_link(self): link = PrivateLinkFactory(anonymous=True) link.nodes.append(self.project) link.save() self._upload_file('firstfile', 'secondcontent') url = self.project.api_url_for('file_info', fid=self.project.uploads[0].filename) res = self.app.get(url, {'view_only': link.key}) assert_not_in(self.user.fullname, res.body) assert_not_in(self.user._id, res.body) def test_delete_file(self): url = self.project.api_url_for('delete_file', fid=self.fid) res = self.app.delete(url, auth=self.auth).maybe_follow() assert_equal(res.status_code, 200) self.project.reload() assert_not_in('firstfile', self.project.files_current) def test_delete_file_returns_404_when_file_is_already_deleted(self): self.project.remove_file(Auth(self.project.creator), self.fid) url = self.project.api_url_for('delete_file', fid=self.fid) res = self.app.delete_json(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) def test_file_urls(self): url = self.project.api_url + 'osffiles/hgrid/' res = self.app.get(url, auth=self.auth).maybe_follow() assert_equal(len(res.json), 1) for url in ['view', 'download', 'delete']: assert_in(self.project._id, res.json[0]['urls'][url]) def test_file_urls_fork(self): fork = self.project.fork_node(auth=Auth(user=self.user)) url = fork.api_url + 'osffiles/hgrid/' res = self.app.get(url, auth=self.auth).maybe_follow() assert_equal(len(res.json), 1) for url in ['view', 'download', 'delete']: assert_in(fork._id, res.json[0]['urls'][url]) def test_file_urls_registration(self): registration = self.project.register_node(None, Auth(user=self.user), '', '') url = registration.api_url + 'osffiles/hgrid/' res = self.app.get(url, auth=self.auth).maybe_follow() assert_equal(len(res.json), 1) for url in ['view', 'download', 'delete']: assert_in(registration._id, res.json[0]['urls'][url]) def test_view_creates_guid(self): guid_fid = 'unique' guid_content = 'snowflake' self._upload_file(guid_fid, guid_content) node_file = NodeFile.load(self.project.files_current[guid_fid]) guid_count = OsfGuidFile.find().count() # View file for the first time url = node_file.url(self.project) res = self.app.get( url, auth=self.user.auth, ).follow(auth=self.user.auth, ) guid = OsfGuidFile.find_one( Q('node', 'eq', self.project) & Q('name', 'eq', guid_fid)) # GUID count has been incremented by one assert_equal(OsfGuidFile.find().count(), guid_count + 1) # Client has been redirected to GUID assert_equal( res.request.path.strip('/'), guid._id, ) # View file for the second time self.app.get( url, auth=self.user.auth, ).follow(auth=self.user.auth, ) # GUID count has not been incremented assert_equal(OsfGuidFile.find().count(), guid_count + 1) def test_guid_url_returns_404(self): f = NodeFile() f.save() url = '/{}/'.format(f._id) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 404) def test_sees_delete_button_if_can_write(self): url = self.project.uploads[0].url(self.project) res = self.app.get( url, auth=self.user.auth, ).maybe_follow(auth=self.user.auth, ) assert_in('Download', res) assert_in('Delete', res) def test_does_not_see_delete_button_if_cannot_write(self): self.project.is_public = True self.project.save() user2 = AuthUserFactory() url = self.project.uploads[0].url(self.project) res = self.app.get( url, auth=user2.auth, ).maybe_follow(auth=user2.auth, ) assert_in('Download', res) assert_not_in('Delete', res)
class TestAddonFileViews(OsfTestCase): @classmethod def setUpClass(cls): super(TestAddonFileViews, cls).setUpClass() PROVIDER_MAP["github"] = [TestFolder, TestFile, TestFileNode] TestFileNode.provider = "github" def setUp(self): super(TestAddonFileViews, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.user.add_addon("github") self.project.add_addon("github", auth=Auth(self.user)) self.user_addon = self.user.get_addon("github") self.node_addon = self.project.get_addon("github") self.oauth = GitHubAccountFactory() self.oauth.save() self.user.external_accounts.append(self.oauth) self.user.save() self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth self.node_addon.repo = "Truth" self.node_addon.user = "******" self.node_addon.save() @classmethod def tearDownClass(cls): super(TestAddonFileViews, cls).tearDownClass() PROVIDER_MAP["github"] = [models.GithubFolder, models.GithubFile, models.GithubFileNode] del PROVIDER_MAP["test_addons"] TrashedFileNode.remove() def get_test_file(self): version = models.FileVersion(identifier="1") version.save() versions = [version] ret = TestFile( name="Test", node=self.project, path="/test/Test", materialized_path="/test/Test", versions=versions ) ret.save() return ret def get_second_test_file(self): version = models.FileVersion(identifier="1") version.save() ret = TestFile( name="Test2", node=self.project, path="/test/Test2", materialized_path="/test/Test2", versions=[version] ) ret.save() return ret def get_mako_return(self): ret = serialize_node(self.project, Auth(self.user), primary=True) ret.update( { "error": "", "provider": "", "file_path": "", "sharejs_uuid": "", "private": "", "urls": { "files": "", "render": "", "sharejs": "", "mfr": "", "gravatar": "", "external": "", "archived_from": "", }, "size": "", "extra": "", "file_name": "", "materialized_path": "", "file_id": "", } ) ret.update(rubeus.collect_addon_assets(self.project)) return ret def test_redirects_to_guid(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.get( self.project.web_url_for("addon_view_or_download_file", path=file_node.path.strip("/"), provider="github"), auth=self.user.auth, ) assert_equals(resp.status_code, 302) assert_equals(resp.location, "http://*****:*****@mock.patch("website.addons.base.views.addon_view_file") def test_action_view_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get("/{}/?action=view".format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) @mock.patch("website.addons.base.views.addon_view_file") def test_no_action_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get("/{}/".format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) def test_download_create_guid(self): file_node = self.get_test_file() assert_is(file_node.get_guid(), None) self.app.get( self.project.web_url_for("addon_view_or_download_file", path=file_node.path.strip("/"), provider="github"), auth=self.user.auth, ) assert_true(file_node.get_guid()) def test_view_file_does_not_delete_file_when_requesting_invalid_version(self): with mock.patch( "website.addons.github.model.GitHubNodeSettings.is_private", new_callable=mock.PropertyMock ) as mock_is_private: mock_is_private.return_value = False file_node = self.get_test_file() assert_is(file_node.get_guid(), None) url = self.project.web_url_for( "addon_view_or_download_file", path=file_node.path.strip("/"), provider="github" ) # First view generated GUID self.app.get(url, auth=self.user.auth) self.app.get(url + "?version=invalid", auth=self.user.auth, expect_errors=True) assert_is_not_none(StoredFileNode.load(file_node._id)) assert_is_none(TrashedFileNode.load(file_node._id)) def test_unauthorized_addons_raise(self): path = "cloudfiles" self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.web_url_for("addon_view_or_download_file", path=path, provider="github", action="download"), auth=self.user.auth, expect_errors=True, ) assert_equals(resp.status_code, 401) def test_nonstorage_addons_raise(self): resp = self.app.get( self.project.web_url_for( "addon_view_or_download_file", path="sillywiki", provider="wiki", action="download" ), auth=self.user.auth, expect_errors=True, ) assert_equals(resp.status_code, 400) def test_head_returns_url(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head("/{}/".format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, version=None)) def test_head_returns_url_with_version(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head("/{}/?revision=1&foo=bar".format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) # Note: version is added but us but all other url params are added as well assert_urls_equal( location.url, file_node.generate_waterbutler_url(direct=None, revision=1, version=None, foo="bar") ) def test_nonexistent_addons_raise(self): path = "cloudfiles" self.project.delete_addon("github", Auth(self.user)) self.project.save() resp = self.app.get( self.project.web_url_for("addon_view_or_download_file", path=path, provider="github", action="download"), auth=self.user.auth, expect_errors=True, ) assert_equals(resp.status_code, 400) def test_unauth_addons_raise(self): path = "cloudfiles" self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.web_url_for("addon_view_or_download_file", path=path, provider="github", action="download"), auth=self.user.auth, expect_errors=True, ) assert_equals(resp.status_code, 401) def test_delete_action_creates_trashed_file_node(self): file_node = self.get_test_file() payload = {"provider": file_node.provider, "metadata": {"path": "/test/Test", "materialized": "/test/Test"}} views.addon_delete_file_node( self=None, node=self.project, user=self.user, event_type="file_removed", payload=payload ) assert_false(StoredFileNode.load(file_node._id)) assert_true(TrashedFileNode.load(file_node._id)) def test_delete_action_for_folder_deletes_subfolders_and_creates_trashed_file_nodes(self): file_node = self.get_test_file() subfolder = TestFolder( name="folder", node=self.project, path="/test/folder/", materialized_path="/test/folder/", versions=[] ) subfolder.save() payload = {"provider": file_node.provider, "metadata": {"path": "/test/", "materialized": "/test/"}} views.addon_delete_file_node( self=None, node=self.project, user=self.user, event_type="file_removed", payload=payload ) assert_false(StoredFileNode.load(file_node._id)) assert_true(TrashedFileNode.load(file_node._id)) assert_false(StoredFileNode.load(subfolder._id)) @mock.patch("website.archiver.tasks.archive") def test_archived_from_url(self, mock_archive): file_node = self.get_test_file() second_file_node = self.get_second_test_file() file_node.copied_from = second_file_node registered_node = self.project.register_node(schema=get_default_metaschema(), auth=Auth(self.user), data=None) archived_from_url = views.get_archived_from_url(registered_node, file_node) view_url = self.project.web_url_for( "addon_view_or_download_file", provider=file_node.provider, path=file_node.copied_from._id ) assert_true(archived_from_url) assert_urls_equal(archived_from_url, view_url) @mock.patch("website.archiver.tasks.archive") def test_archived_from_url_without_copied_from(self, mock_archive): file_node = self.get_test_file() registered_node = self.project.register_node(schema=get_default_metaschema(), auth=Auth(self.user), data=None) archived_from_url = views.get_archived_from_url(registered_node, file_node) assert_false(archived_from_url) @mock.patch("website.archiver.tasks.archive") def test_copied_from_id_trashed(self, mock_archive): file_node = self.get_test_file() second_file_node = self.get_second_test_file() file_node.copied_from = second_file_node self.project.register_node(schema=get_default_metaschema(), auth=Auth(self.user), data=None) trashed_node = second_file_node.delete() assert_false(trashed_node.copied_from)