def test_returns_addon_folders(self): user_auth = Auth(self.user) res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(len(res.json['data']), 1) assert_equal(res.json['data'][0]['attributes']['provider'], 'osfstorage') self.project.add_addon('github', auth=user_auth) addon = self.project.get_addon('github') addon.repo = 'something' addon.user = '******' oauth_settings = GitHubAccountFactory() oauth_settings.save() self.user.add_addon('github') self.user.external_accounts.append(oauth_settings) self.user.save() addon.user_settings = self.user.get_addon('github') addon.save() self.project.save() res = self.app.get(self.private_url, auth=self.user.auth) data = res.json['data'] providers = [item['attributes']['provider'] for item in data] assert_equal(len(data), 2) assert_in('github', providers) assert_in('osfstorage', providers)
def test_one_user_with_multiple_githubs(self): oauth_settings2 = GitHubAccountFactory(display_name='hmoco2') oauth_settings2.save() self.user.external_accounts.append(oauth_settings2) self.user.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['users']['total'], 1)
def test_one_user_with_multiple_githubs(self): oauth_settings2 = GitHubAccountFactory(display_name="hmoco2") oauth_settings2.save() self.user.external_accounts.append(oauth_settings2) self.user.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res["provider"]["name"] == "github"][0] assert_equal(github_res["users"]["enabled"], 1)
def test_one_user_with_multiple_githubs(self): oauth_settings2 = GitHubAccountFactory(display_name='hmoco2') oauth_settings2.save() self.user.external_accounts.append(oauth_settings2) self.user.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['users']['total'], 1)
def test_many_users_each_with_a_different_github(self): user = AuthUserFactory() user.add_addon('github') oauth_settings2 = GitHubAccountFactory(display_name='hmoco2') oauth_settings2.save() user.external_accounts.append(oauth_settings2) user.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['users']['total'], 2)
def test_many_users_each_with_a_different_github(self): user = AuthUserFactory() user.add_addon('github') oauth_settings2 = GitHubAccountFactory(display_name='hmoco2') oauth_settings2.save() user.external_accounts.append(oauth_settings2) user.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['users']['total'], 2)
def test_many_users_each_with_a_different_github(self): user = AuthUserFactory() user.add_addon("github") oauth_settings2 = GitHubAccountFactory(display_name="hmoco2") oauth_settings2.save() user.external_accounts.append(oauth_settings2) user.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res["provider"]["name"] == "github"][0] assert_equal(github_res["users"]["enabled"], 2) assert_equal(github_res["users"]["authorized"], 1) assert_equal(github_res["users"]["linked"], 1)
def add_github(self): user_auth = Auth(self.user) self.project.add_addon('github', auth=user_auth) addon = self.project.get_addon('github') addon.repo = 'something' addon.user = '******' oauth_settings = GitHubAccountFactory() oauth_settings.save() self.user.add_addon('github') self.user.external_accounts.append(oauth_settings) self.user.save() addon.user_settings = self.user.get_addon('github') addon.save() self.project.save()
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 TestAddonLogs(OsfTestCase): def setUp(self): super(TestAddonLogs, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = GitHubAccountFactory(display_name='john') self.oauth_settings.save() self.user.external_accounts.append(self.oauth_settings) self.user.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() def build_payload(self, metadata, **kwargs): options = dict( auth={'id': self.user._id}, action='create', provider=self.node_addon.config.short_name, metadata=metadata, time=time.time() + 1000, ) options.update(kwargs) options = { key: value for key, value in options.iteritems() if value is not None } message, signature = signing.default_signer.sign_payload(options) return { 'payload': message, 'signature': signature, } @mock.patch('website.notifications.events.files.FileAdded.perform') def test_add_log(self, mock_perform): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = len(self.node.logs) self.app.put_json(url, payload, headers={'Content-Type': 'application/json'}) self.node.reload() assert_equal(len(self.node.logs), nlogs + 1) # # Mocking form_message and perform so that the payload need not be exact. # assert_true(mock_form_message.called, "form_message not called") assert_true(mock_perform.called, "perform not called") def test_add_log_missing_args(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth=None) nlogs = len(self.node.logs) res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_add_log_no_user(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth={'id': None}) nlogs = len(self.node.logs) res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_add_log_no_addon(self): path = 'pizza' node = ProjectFactory(creator=self.user) url = node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = len(node.logs) res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(node.logs), nlogs) def test_add_log_bad_action(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, action='dance') nlogs = len(self.node.logs) res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_action_file_rename(self): url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload( action='rename', metadata={ 'path': 'foo', }, source={ 'materialized': 'foo', 'provider': 'github', 'node': {'_id': self.node._id}, 'name': 'new.txt', 'kind': 'file', }, destination={ 'path': 'foo', 'materialized': 'foo', 'provider': 'github', 'node': {'_id': self.node._id}, 'name': 'old.txt', 'kind': 'file', }, ) self.app.put_json( url, payload, headers={'Content-Type': 'application/json'} ) self.node.reload() assert_equal( self.node.logs[-1].action, 'github_addon_file_renamed', )
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_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': '', }, '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))
class TestAddonAuth(OsfTestCase): def setUp(self): super(TestAddonAuth, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() self.JWE_KEY = jwe.kdf(settings.WATERBUTLER_JWE_SECRET.encode('utf-8'), settings.WATERBUTLER_JWE_SALT.encode('utf-8')) def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = GitHubAccountFactory(display_name='john') self.oauth_settings.save() self.user.external_accounts.append(self.oauth_settings) self.user.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() def build_url(self, **kwargs): options = {'payload': jwe.encrypt(jwt.encode({'data': dict(dict( action='download', nid=self.node._id, provider=self.node_addon.config.short_name, ), **kwargs), 'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=settings.WATERBUTLER_JWT_EXPIRATION), }, settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM), self.JWE_KEY)} return api_url_for('get_auth', **options) def test_auth_download(self): url = self.build_url() res = self.app.get(url, auth=self.user.auth) data = jwt.decode(jwe.decrypt(res.json['payload'].encode('utf-8'), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM)['data'] assert_equal(data['auth'], views.make_auth(self.user)) assert_equal(data['credentials'], self.node_addon.serialize_waterbutler_credentials()) assert_equal(data['settings'], self.node_addon.serialize_waterbutler_settings()) expected_url = furl.furl(self.node.api_url_for('create_waterbutler_log', _absolute=True)) observed_url = furl.furl(data['callback_url']) observed_url.port = expected_url.port assert_equal(expected_url, observed_url) def test_auth_missing_args(self): url = self.build_url(cookie=None) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_auth_bad_cookie(self): url = self.build_url(cookie=self.cookie) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 200) data = jwt.decode(jwe.decrypt(res.json['payload'].encode('utf-8'), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM)['data'] assert_equal(data['auth'], views.make_auth(self.user)) assert_equal(data['credentials'], self.node_addon.serialize_waterbutler_credentials()) assert_equal(data['settings'], self.node_addon.serialize_waterbutler_settings()) expected_url = furl.furl(self.node.api_url_for('create_waterbutler_log', _absolute=True)) observed_url = furl.furl(data['callback_url']) observed_url.port = expected_url.port assert_equal(expected_url, observed_url) def test_auth_cookie(self): url = self.build_url(cookie=self.cookie[::-1]) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_auth_missing_addon(self): url = self.build_url(provider='queenhub') res = self.app.get(url, expect_errors=True, auth=self.user.auth) assert_equal(res.status_code, 400) @mock.patch('website.addons.base.views.cas.get_client') def test_auth_bad_bearer_token(self, mock_cas_client): mock_cas_client.return_value = mock.Mock(profile=mock.Mock(return_value=cas.CasResponse(authenticated=False))) url = self.build_url() res = self.app.get(url, headers={'Authorization': 'Bearer invalid_access_token'}, expect_errors=True) assert_equal(res.status_code, 403)
class TestAddonCount(OsfTestCase): def setUp(self): super(TestAddonCount, self).setUp() self.user = AuthUserFactory() self.node = ProjectFactory(creator=self.user) self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = GitHubAccountFactory(display_name='hmoco1') self.oauth_settings.save() self.user.external_accounts.append(self.oauth_settings) self.user.save() self.node.add_addon('github', Auth(self.user)) self.node_addon = self.node.get_addon('github') self.node_addon.user = self.user.fullname self.node_addon.repo = '29 #Strafford APTS' self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() def tearDown(self): GitHubNodeSettings.remove() GitHubUserSettings.remove() GoogleDriveNodeSettings.remove() GoogleDriveUserSettings.remove() def test_run_for_all_addon(self): results = AddonSnapshot().get_events() names = [res['provider']['name'] for res in results] for addon in ADDONS_AVAILABLE: assert_in(addon.short_name, names) def test_one_user_one_node_one_addon(self): results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['users']['total'], 1) assert_equal(github_res['nodes']['total'], 1) def test_one_user_with_multiple_githubs(self): oauth_settings2 = GitHubAccountFactory(display_name='hmoco2') oauth_settings2.save() self.user.external_accounts.append(oauth_settings2) self.user.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['users']['total'], 1) def test_one_user_with_multiple_addons(self): results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] googledrive_res = [res for res in results if res['provider']['name'] == 'googledrive'][0] assert_equal(github_res['users']['total'], 1) assert_equal(googledrive_res['users']['total'], 0) self.user.add_addon('googledrive') oauth_settings = GoogleDriveAccountFactory() oauth_settings.save() self.user.external_accounts.append(oauth_settings) self.user.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] googledrive_res = [res for res in results if res['provider']['name'] == 'googledrive'][0] assert_equal(github_res['users']['total'], 1) assert_equal(googledrive_res['users']['total'], 1) def test_many_users_each_with_a_different_github(self): user = AuthUserFactory() user.add_addon('github') oauth_settings2 = GitHubAccountFactory(display_name='hmoco2') oauth_settings2.save() user.external_accounts.append(oauth_settings2) user.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['users']['total'], 2) def test_many_users_each_with_the_same_github(self): user = AuthUserFactory() user.add_addon('github') user.external_accounts.append(self.oauth_settings) user.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['users']['total'], 2) def test_one_node_with_multiple_addons(self): results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] googledrive_res = [res for res in results if res['provider']['name'] == 'googledrive'][0] assert_equal(github_res['nodes']['total'], 1) assert_equal(googledrive_res['nodes']['total'], 0) self.user.add_addon('googledrive') user_addon = self.user.get_addon('googledrive') oauth_settings = GoogleDriveAccountFactory() oauth_settings.save() self.user.external_accounts.append(oauth_settings) self.user.save() self.node.add_addon('googledrive', Auth(self.user)) node_addon = self.node.get_addon('googledrive') node_addon.user = self.user.fullname node_addon.user_settings = user_addon node_addon.external_account = oauth_settings node_addon.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] googledrive_res = [res for res in results if res['provider']['name'] == 'googledrive'][0] assert_equal(github_res['nodes']['total'], 1) assert_equal(googledrive_res['nodes']['total'], 1) def test_many_nodes_with_one_addon(self): results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['total'], 1) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.user = self.user.fullname node_addon.repo = '8 (circle)' node_addon.user_settings = self.user_addon node_addon.external_account = self.oauth_settings node_addon.save() node.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['total'], 2) def test_node_count_deleted_addon(self): results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['deleted'], 0) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.delete() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['deleted'], 1) def test_node_count_disconected_addon(self): results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['disconnected'], 0) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.external_account = None node_addon.save() results = AddonSnapshot().get_events() github_res = [res for res in results if res['provider']['name'] == 'github'][0] assert_equal(github_res['nodes']['disconnected'], 1)
class TestAddonCount(OsfTestCase): def setUp(self): super(TestAddonCount, self).setUp() self.user = AuthUserFactory() self.node = ProjectFactory(creator=self.user) self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = GitHubAccountFactory(display_name='hmoco1') self.oauth_settings.save() self.user.external_accounts.append(self.oauth_settings) self.user.save() self.node.add_addon('github', Auth(self.user)) self.node_addon = self.node.get_addon('github') self.node_addon.user = self.user.fullname self.node_addon.repo = '29 #Strafford APTS' self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() def tearDown(self): GitHubNodeSettings.remove() GitHubUserSettings.remove() GoogleDriveNodeSettings.remove() GoogleDriveUserSettings.remove() def test_run_for_all_addon(self): results = AddonSnapshot().get_events() names = [res['provider']['name'] for res in results] for addon in ADDONS_AVAILABLE: assert_in(addon.short_name, names) def test_one_user_one_node_one_addon(self): results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['users']['total'], 1) assert_equal(github_res['nodes']['total'], 1) def test_one_user_with_multiple_githubs(self): oauth_settings2 = GitHubAccountFactory(display_name='hmoco2') oauth_settings2.save() self.user.external_accounts.append(oauth_settings2) self.user.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['users']['total'], 1) def test_one_user_with_multiple_addons(self): results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] googledrive_res = [ res for res in results if res['provider']['name'] == 'googledrive' ][0] assert_equal(github_res['users']['total'], 1) assert_equal(googledrive_res['users']['total'], 0) self.user.add_addon('googledrive') oauth_settings = GoogleDriveAccountFactory() oauth_settings.save() self.user.external_accounts.append(oauth_settings) self.user.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] googledrive_res = [ res for res in results if res['provider']['name'] == 'googledrive' ][0] assert_equal(github_res['users']['total'], 1) assert_equal(googledrive_res['users']['total'], 1) def test_many_users_each_with_a_different_github(self): user = AuthUserFactory() user.add_addon('github') oauth_settings2 = GitHubAccountFactory(display_name='hmoco2') oauth_settings2.save() user.external_accounts.append(oauth_settings2) user.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['users']['total'], 2) def test_many_users_each_with_the_same_github(self): user = AuthUserFactory() user.add_addon('github') user.external_accounts.append(self.oauth_settings) user.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['users']['total'], 2) def test_one_node_with_multiple_addons(self): results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] googledrive_res = [ res for res in results if res['provider']['name'] == 'googledrive' ][0] assert_equal(github_res['nodes']['total'], 1) assert_equal(googledrive_res['nodes']['total'], 0) self.user.add_addon('googledrive') user_addon = self.user.get_addon('googledrive') oauth_settings = GoogleDriveAccountFactory() oauth_settings.save() self.user.external_accounts.append(oauth_settings) self.user.save() self.node.add_addon('googledrive', Auth(self.user)) node_addon = self.node.get_addon('googledrive') node_addon.user = self.user.fullname node_addon.user_settings = user_addon node_addon.external_account = oauth_settings node_addon.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] googledrive_res = [ res for res in results if res['provider']['name'] == 'googledrive' ][0] assert_equal(github_res['nodes']['total'], 1) assert_equal(googledrive_res['nodes']['total'], 1) def test_many_nodes_with_one_addon(self): results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['total'], 1) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.user = self.user.fullname node_addon.repo = '8 (circle)' node_addon.user_settings = self.user_addon node_addon.external_account = self.oauth_settings node_addon.save() node.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['total'], 2) def test_node_count_deleted_addon(self): results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['deleted'], 0) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.delete() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['deleted'], 1) def test_node_count_disconected_addon(self): results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['disconnected'], 0) node = ProjectFactory(creator=self.user) node.add_addon('github', Auth(self.user)) node_addon = node.get_addon('github') node_addon.external_account = None node_addon.save() results = AddonSnapshot().get_events() github_res = [ res for res in results if res['provider']['name'] == 'github' ][0] assert_equal(github_res['nodes']['disconnected'], 1)
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 TestAddonLogs(OsfTestCase): def setUp(self): super(TestAddonLogs, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign( self.session._id) self.configure_addon() def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = GitHubAccountFactory(display_name='john') self.oauth_settings.save() self.user.external_accounts.append(self.oauth_settings) self.user.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() def build_payload(self, metadata, **kwargs): options = dict( auth={'id': self.user._id}, action='create', provider=self.node_addon.config.short_name, metadata=metadata, time=time.time() + 1000, ) options.update(kwargs) options = { key: value for key, value in options.iteritems() if value is not None } message, signature = signing.default_signer.sign_payload(options) return { 'payload': message, 'signature': signature, } @mock.patch('website.notifications.events.files.FileAdded.perform') def test_add_log(self, mock_perform): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = len(self.node.logs) self.app.put_json(url, payload, headers={'Content-Type': 'application/json'}) self.node.reload() assert_equal(len(self.node.logs), nlogs + 1) # # Mocking form_message and perform so that the payload need not be exact. # assert_true(mock_form_message.called, "form_message not called") assert_true(mock_perform.called, "perform not called") def test_add_log_missing_args(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth=None) nlogs = len(self.node.logs) res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_add_log_no_user(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, auth={'id': None}) nlogs = len(self.node.logs) res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_add_log_no_addon(self): path = 'pizza' node = ProjectFactory(creator=self.user) url = node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}) nlogs = len(node.logs) res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(node.logs), nlogs) def test_add_log_bad_action(self): path = 'pizza' url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload(metadata={'path': path}, action='dance') nlogs = len(self.node.logs) res = self.app.put_json( url, payload, headers={'Content-Type': 'application/json'}, expect_errors=True, ) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_action_file_rename(self): url = self.node.api_url_for('create_waterbutler_log') payload = self.build_payload( action='rename', metadata={ 'path': 'foo', }, source={ 'materialized': 'foo', 'provider': 'github', 'node': { '_id': self.node._id }, 'name': 'new.txt', 'kind': 'file', }, destination={ 'path': 'foo', 'materialized': 'foo', 'provider': 'github', 'node': { '_id': self.node._id }, 'name': 'old.txt', 'kind': 'file', }, ) self.app.put_json(url, payload, headers={'Content-Type': 'application/json'}) self.node.reload() assert_equal( self.node.logs[-1].action, 'github_addon_file_renamed', )
class TestAddonAuth(OsfTestCase): def setUp(self): super(TestAddonAuth, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={'auth_user_id': self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign( self.session._id) self.configure_addon() self.JWE_KEY = jwe.kdf(settings.WATERBUTLER_JWE_SECRET.encode('utf-8'), settings.WATERBUTLER_JWE_SALT.encode('utf-8')) def configure_addon(self): self.user.add_addon('github') self.user_addon = self.user.get_addon('github') self.oauth_settings = GitHubAccountFactory(display_name='john') self.oauth_settings.save() self.user.external_accounts.append(self.oauth_settings) self.user.save() self.node.add_addon('github', self.auth_obj) self.node_addon = self.node.get_addon('github') self.node_addon.user = '******' self.node_addon.repo = 'youre-my-best-friend' self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() def build_url(self, **kwargs): options = { 'payload': jwe.encrypt( jwt.encode( { 'data': dict( dict( action='download', nid=self.node._id, provider=self.node_addon.config.short_name, ), **kwargs), 'exp': datetime.datetime.utcnow() + datetime.timedelta( seconds=settings.WATERBUTLER_JWT_EXPIRATION), }, settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM), self.JWE_KEY) } return api_url_for('get_auth', **options) def test_auth_download(self): url = self.build_url() res = self.app.get(url, auth=self.user.auth) data = jwt.decode(jwe.decrypt(res.json['payload'].encode('utf-8'), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM)['data'] assert_equal(data['auth'], views.make_auth(self.user)) assert_equal(data['credentials'], self.node_addon.serialize_waterbutler_credentials()) assert_equal(data['settings'], self.node_addon.serialize_waterbutler_settings()) expected_url = furl.furl( self.node.api_url_for('create_waterbutler_log', _absolute=True)) observed_url = furl.furl(data['callback_url']) observed_url.port = expected_url.port assert_equal(expected_url, observed_url) def test_auth_missing_args(self): url = self.build_url(cookie=None) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_auth_bad_cookie(self): url = self.build_url(cookie=self.cookie) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 200) data = jwt.decode(jwe.decrypt(res.json['payload'].encode('utf-8'), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM)['data'] assert_equal(data['auth'], views.make_auth(self.user)) assert_equal(data['credentials'], self.node_addon.serialize_waterbutler_credentials()) assert_equal(data['settings'], self.node_addon.serialize_waterbutler_settings()) expected_url = furl.furl( self.node.api_url_for('create_waterbutler_log', _absolute=True)) observed_url = furl.furl(data['callback_url']) observed_url.port = expected_url.port assert_equal(expected_url, observed_url) def test_auth_cookie(self): url = self.build_url(cookie=self.cookie[::-1]) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 401) def test_auth_missing_addon(self): url = self.build_url(provider='queenhub') res = self.app.get(url, expect_errors=True, auth=self.user.auth) assert_equal(res.status_code, 400) @mock.patch('website.addons.base.views.cas.get_client') def test_auth_bad_bearer_token(self, mock_cas_client): mock_cas_client.return_value = mock.Mock(profile=mock.Mock( return_value=cas.CasResponse(authenticated=False))) url = self.build_url() res = self.app.get( url, headers={'Authorization': 'Bearer invalid_access_token'}, expect_errors=True) assert_equal(res.status_code, 403)
class TestAddonLogs(OsfTestCase): def setUp(self): super(TestAddonLogs, self).setUp() self.user = AuthUserFactory() self.auth_obj = Auth(user=self.user) self.node = ProjectFactory(creator=self.user) self.session = Session(data={"auth_user_id": self.user._id}) self.session.save() self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id) self.configure_addon() def configure_addon(self): self.user.add_addon("github") self.user_addon = self.user.get_addon("github") self.oauth_settings = GitHubAccountFactory(display_name="john") self.oauth_settings.save() self.user.external_accounts.append(self.oauth_settings) self.user.save() self.node.add_addon("github", self.auth_obj) self.node_addon = self.node.get_addon("github") self.node_addon.user = "******" self.node_addon.repo = "youre-my-best-friend" self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth_settings self.node_addon.save() def build_payload(self, metadata, **kwargs): options = dict( auth={"id": self.user._id}, action="create", provider=self.node_addon.config.short_name, metadata=metadata, time=time.time() + 1000, ) options.update(kwargs) options = {key: value for key, value in options.iteritems() if value is not None} message, signature = signing.default_signer.sign_payload(options) return {"payload": message, "signature": signature} @mock.patch("website.notifications.events.files.FileAdded.perform") def test_add_log(self, mock_perform): path = "pizza" url = self.node.api_url_for("create_waterbutler_log") payload = self.build_payload(metadata={"path": path}) nlogs = len(self.node.logs) self.app.put_json(url, payload, headers={"Content-Type": "application/json"}) self.node.reload() assert_equal(len(self.node.logs), nlogs + 1) # # Mocking form_message and perform so that the payload need not be exact. # assert_true(mock_form_message.called, "form_message not called") assert_true(mock_perform.called, "perform not called") def test_add_log_missing_args(self): path = "pizza" url = self.node.api_url_for("create_waterbutler_log") payload = self.build_payload(metadata={"path": path}, auth=None) nlogs = len(self.node.logs) res = self.app.put_json(url, payload, headers={"Content-Type": "application/json"}, expect_errors=True) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_add_log_no_user(self): path = "pizza" url = self.node.api_url_for("create_waterbutler_log") payload = self.build_payload(metadata={"path": path}, auth={"id": None}) nlogs = len(self.node.logs) res = self.app.put_json(url, payload, headers={"Content-Type": "application/json"}, expect_errors=True) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_add_log_no_addon(self): path = "pizza" node = ProjectFactory(creator=self.user) url = node.api_url_for("create_waterbutler_log") payload = self.build_payload(metadata={"path": path}) nlogs = len(node.logs) res = self.app.put_json(url, payload, headers={"Content-Type": "application/json"}, expect_errors=True) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(node.logs), nlogs) def test_add_log_bad_action(self): path = "pizza" url = self.node.api_url_for("create_waterbutler_log") payload = self.build_payload(metadata={"path": path}, action="dance") nlogs = len(self.node.logs) res = self.app.put_json(url, payload, headers={"Content-Type": "application/json"}, expect_errors=True) assert_equal(res.status_code, 400) self.node.reload() assert_equal(len(self.node.logs), nlogs) def test_action_file_rename(self): url = self.node.api_url_for("create_waterbutler_log") payload = self.build_payload( action="rename", metadata={"path": "foo"}, source={ "materialized": "foo", "provider": "github", "node": {"_id": self.node._id}, "name": "new.txt", "kind": "file", }, destination={ "path": "foo", "materialized": "foo", "provider": "github", "node": {"_id": self.node._id}, "name": "old.txt", "kind": "file", }, ) self.app.put_json(url, payload, headers={"Content-Type": "application/json"}) self.node.reload() assert_equal(self.node.logs[-1].action, "github_addon_file_renamed")