示例#1
0
class TestGoogleDriveUtils(OsfTestCase):

    def setUp(self):
        super(TestGoogleDriveUtils, self).setUp()
        self.user = AuthUserFactory()
        self.user.add_addon('googledrive')
        self.project = ProjectFactory(creator=self.user)
        self.project.add_addon('googledrive', Auth(self.user))
        self.node_settings = self.project.get_addon('googledrive')
        self.user_settings = self.user.get_addon('googledrive')
        oauth_settings = GoogleDriveOAuthSettingsFactory()
        self.user_settings.oauth_settings = oauth_settings
        self.node_settings.user_settings = self.user_settings
        self.node_settings.folder_id = '09120912'
        self.node_settings.folder_path = 'foo/bar'

        self.user_settings.save()
        self.node_settings.save()
        # Log user in
        self.app.authenticate(*self.user.auth)

    def test_serialize_settings_helper_returns_correct_urls(self):
        result = serialize_settings(self.node_settings, self.user)
        urls = result['urls']

        assert_equal(urls['files'], self.project.web_url_for('collect_file_trees'))
        assert_equal(urls['config'], self.project.api_url_for('googledrive_config_put'))
        assert_equal(urls['deauthorize'], self.project.api_url_for('googledrive_deauthorize'))
        assert_equal(urls['importAuth'], self.project.api_url_for('googledrive_import_user_auth'))
        # Includes endpoint for fetching folders only
        # NOTE: Querystring params are in camelCase
        assert_equal(urls['get_folders'], self.project.api_url_for('googledrive_folders'))

    def test_serialize_settings_helper_returns_correct_auth_info(self):
        self.user_settings.access_token = 'abc123'
        result = serialize_settings(self.node_settings, self.user)
        assert_equal(result['nodeHasAuth'], self.node_settings.has_auth)
        assert_true(result['userHasAuth'])
        assert_true(result['userIsOwner'])

    def test_serialize_settings_for_user_no_auth(self):
        no_addon_user = AuthUserFactory()
        result = serialize_settings(self.node_settings, no_addon_user)
        assert_false(result['userIsOwner'])
        assert_false(result['userHasAuth'])

    def test_googledrive_import_user_auth_returns_serialized_settings(self):
        self.node_settings.user_settings = None
        self.node_settings.save()
        url = api_url_for('googledrive_import_user_auth', pid=self.project._primary_key)
        res = self.app.put(url, auth=self.user.auth)
        self.project.reload()
        self.node_settings.reload()

        expected_result = serialize_settings(self.node_settings, self.user)
        result = res.json['result']
        assert_equal(result, expected_result)
示例#2
0
class TestGoogleDriveUtils(OsfTestCase):

    def setUp(self):
        super(TestGoogleDriveUtils, self).setUp()
        self.user = AuthUserFactory()
        self.user.add_addon('googledrive')
        self.project = ProjectFactory(creator=self.user)
        self.project.add_addon('googledrive', Auth(self.user))
        self.node_settings = self.project.get_addon('googledrive')
        self.user_settings = self.user.get_addon('googledrive')
        oauth_settings = GoogleDriveOAuthSettingsFactory()
        self.user_settings.oauth_settings = oauth_settings
        self.node_settings.user_settings = self.user_settings
        self.node_settings.folder_id = '09120912'
        self.node_settings.folder_path = 'foo/bar'

        self.user_settings.save()
        self.node_settings.save()
        # Log user in
        self.app.authenticate(*self.user.auth)

    def test_serialize_settings_helper_returns_correct_urls(self):
        result = serialize_settings(self.node_settings, self.user)
        urls = result['urls']

        assert_equal(urls['files'], self.project.web_url_for('collect_file_trees'))
        assert_equal(urls['config'], self.project.api_url_for('googledrive_config_put'))
        assert_equal(urls['deauthorize'], self.project.api_url_for('googledrive_deauthorize'))
        assert_equal(urls['importAuth'], self.project.api_url_for('googledrive_import_user_auth'))
        # Includes endpoint for fetching folders only
        # NOTE: Querystring params are in camelCase
        assert_equal(urls['get_folders'], self.project.api_url_for('googledrive_folders'))

    def test_serialize_settings_helper_returns_correct_auth_info(self):
        self.user_settings.access_token = 'abc123'
        result = serialize_settings(self.node_settings, self.user)
        assert_equal(result['nodeHasAuth'], self.node_settings.has_auth)
        assert_true(result['userHasAuth'])
        assert_true(result['userIsOwner'])

    def test_serialize_settings_for_user_no_auth(self):
        no_addon_user = AuthUserFactory()
        result = serialize_settings(self.node_settings, no_addon_user)
        assert_false(result['userIsOwner'])
        assert_false(result['userHasAuth'])

    def test_googledrive_import_user_auth_returns_serialized_settings(self):
        self.node_settings.user_settings = None
        self.node_settings.save()
        url = api_url_for('googledrive_import_user_auth', pid=self.project._primary_key)
        res = self.app.put(url, auth=self.user.auth)
        self.project.reload()
        self.node_settings.reload()

        expected_result = serialize_settings(self.node_settings, self.user)
        result = res.json['result']
        assert_equal(result, expected_result)
示例#3
0
class TestCommentViews(OsfTestCase):

    def setUp(self):
        super(TestCommentViews, self).setUp()
        self.project = ProjectFactory(is_public=True)
        self.user = AuthUserFactory()
        self.project.add_contributor(self.user)
        self.project.save()
        self.user.save()

    def test_view_project_comments_updates_user_comments_view_timestamp(self):
        url = self.project.api_url_for('update_comments_timestamp')
        res = self.app.put_json(url, {
            'page': 'node',
            'rootId': self.project._id
        }, auth=self.user.auth)
        self.user.reload()

        user_timestamp = self.user.comments_viewed_timestamp[self.project._id]
        view_timestamp = dt.datetime.utcnow()
        assert_datetime_equal(user_timestamp, view_timestamp)

    def test_confirm_non_contrib_viewers_dont_have_pid_in_comments_view_timestamp(self):
        non_contributor = AuthUserFactory()
        url = self.project.api_url_for('update_comments_timestamp')
        res = self.app.put_json(url, {
            'page': 'node',
            'rootId': self.project._id
        }, auth=self.user.auth)

        non_contributor.reload()
        assert_not_in(self.project._id, non_contributor.comments_viewed_timestamp)

    def test_view_comments_updates_user_comments_view_timestamp_files(self):
        osfstorage = self.project.get_addon('osfstorage')
        root_node = osfstorage.get_root()
        test_file = root_node.append_file('test_file')
        test_file.create_version(self.user, {
            'object': '06d80e',
            'service': 'cloud',
            osfstorage_settings.WATERBUTLER_RESOURCE: 'osf',
        }, {
            'size': 1337,
            'contentType': 'img/png'
        }).save()

        url = self.project.api_url_for('update_comments_timestamp')
        res = self.app.put_json(url, {
            'page': 'files',
            'rootId': test_file._id
        }, auth=self.user.auth)
        self.user.reload()

        user_timestamp = self.user.comments_viewed_timestamp[test_file._id]
        view_timestamp = dt.datetime.utcnow()
        assert_datetime_equal(user_timestamp, view_timestamp)
示例#4
0
class TestCommentViews(OsfTestCase):

    def setUp(self):
        super(TestCommentViews, self).setUp()
        self.project = ProjectFactory(is_public=True)
        self.user = AuthUserFactory()
        self.project.add_contributor(self.user)
        self.project.save()
        self.user.save()

    def test_view_project_comments_updates_user_comments_view_timestamp(self):
        url = self.project.api_url_for('update_comments_timestamp')
        res = self.app.put_json(url, {
            'page': 'node',
            'rootId': self.project._id
        }, auth=self.user.auth)
        self.user.reload()

        user_timestamp = self.user.comments_viewed_timestamp[self.project._id]['node']
        view_timestamp = dt.datetime.utcnow()
        assert_datetime_equal(user_timestamp, view_timestamp)

    def test_confirm_non_contrib_viewers_dont_have_pid_in_comments_view_timestamp(self):
        non_contributor = AuthUserFactory()
        url = self.project.api_url_for('update_comments_timestamp')
        res = self.app.put_json(url, {
            'page': 'node',
            'rootId': self.project._id
        }, auth=self.user.auth)

        non_contributor.reload()
        assert_not_in(self.project._id, non_contributor.comments_viewed_timestamp)

    def test_view_comments_updates_user_comments_view_timestamp_files(self):
        osfstorage = self.project.get_addon('osfstorage')
        root_node = osfstorage.get_root()
        test_file = root_node.append_file('test_file')
        test_file.create_version(self.user, {
            'object': '06d80e',
            'service': 'cloud',
            osfstorage_settings.WATERBUTLER_RESOURCE: 'osf',
        }, {
            'size': 1337,
            'contentType': 'img/png'
        }).save()

        url = self.project.api_url_for('update_comments_timestamp')
        res = self.app.put_json(url, {
            'page': 'files',
            'rootId': test_file._id
        }, auth=self.user.auth)
        self.user.reload()

        user_timestamp = self.user.comments_viewed_timestamp[self.project._id]['files'][test_file._id]
        view_timestamp = dt.datetime.utcnow()
        assert_datetime_equal(user_timestamp, view_timestamp)
示例#5
0
class TestWikiDelete(OsfTestCase):

    def setUp(self):
        super(TestWikiDelete, self).setUp()

        self.project = ProjectFactory(is_public=True)
        api_key = ApiKeyFactory()
        self.project.creator.api_keys.append(api_key)
        self.project.creator.save()
        self.consolidate_auth = Auth(user=self.project.creator, api_key=api_key)
        self.auth = ('test', api_key._primary_key)
        self.project.update_node_wiki('Elephants', 'Hello Elephants', self.consolidate_auth)
        self.project.update_node_wiki('Lions', 'Hello Lions', self.consolidate_auth)
        self.elephant_wiki = self.project.get_wiki_page('Elephants')
        self.lion_wiki = self.project.get_wiki_page('Lions')

    @mock.patch('website.addons.wiki.utils.broadcast_to_sharejs')
    def test_project_wiki_delete(self, mock_shrejs):
        assert_in('elephants', self.project.wiki_pages_current)
        url = self.project.api_url_for(
            'project_wiki_delete',
            wname='elephants'
        )
        self.app.delete(
            url,
            auth=self.auth
        )
        self.project.reload()
        assert_not_in('elephants', self.project.wiki_pages_current)

    @mock.patch('website.addons.wiki.utils.broadcast_to_sharejs')
    def test_project_wiki_delete_w_valid_special_characters(self, mock_sharejs):
        # TODO: Need to understand why calling update_node_wiki with failure causes transaction rollback issue later
        # with assert_raises(NameInvalidError):
        #     self.project.update_node_wiki(SPECIAL_CHARACTERS_ALL, 'Hello Special Characters', self.consolidate_auth)
        self.project.update_node_wiki(SPECIAL_CHARACTERS_ALLOWED, 'Hello Special Characters', self.consolidate_auth)
        self.special_characters_wiki = self.project.get_wiki_page(SPECIAL_CHARACTERS_ALLOWED)
        assert_in(to_mongo_key(SPECIAL_CHARACTERS_ALLOWED), self.project.wiki_pages_current)
        url = self.project.api_url_for(
            'project_wiki_delete',
            wname=SPECIAL_CHARACTERS_ALLOWED
        )
        self.app.delete(
            url,
            auth=self.auth
        )
        self.project.reload()
        assert_not_in(to_mongo_key(SPECIAL_CHARACTERS_ALLOWED), self.project.wiki_pages_current)
示例#6
0
class TestWikiDelete(OsfTestCase):

    def setUp(self):
        super(TestWikiDelete, self).setUp()

        self.project = ProjectFactory(is_public=True)
        api_key = ApiKeyFactory()
        self.project.creator.api_keys.append(api_key)
        self.project.creator.save()
        self.consolidate_auth = Auth(user=self.project.creator, api_key=api_key)
        self.auth = ('test', api_key._primary_key)
        self.project.update_node_wiki('Elephants', 'Hello Elephants', self.consolidate_auth)
        self.project.update_node_wiki('Lions', 'Hello Lions', self.consolidate_auth)
        self.elephant_wiki = self.project.get_wiki_page('Elephants')
        self.lion_wiki = self.project.get_wiki_page('Lions')

    @mock.patch('website.addons.wiki.utils.broadcast_to_sharejs')
    def test_project_wiki_delete(self, mock_shrejs):
        assert_in('elephants', self.project.wiki_pages_current)
        url = self.project.api_url_for(
            'project_wiki_delete',
            wname='elephants'
        )
        self.app.delete(
            url,
            auth=self.auth
        )
        self.project.reload()
        assert_not_in('elephants', self.project.wiki_pages_current)

    @mock.patch('website.addons.wiki.utils.broadcast_to_sharejs')
    def test_project_wiki_delete_w_valid_special_characters(self, mock_sharejs):
        # TODO: Need to understand why calling update_node_wiki with failure causes transaction rollback issue later
        # with assert_raises(NameInvalidError):
        #     self.project.update_node_wiki(SPECIAL_CHARACTERS_ALL, 'Hello Special Characters', self.consolidate_auth)
        self.project.update_node_wiki(SPECIAL_CHARACTERS_ALLOWED, 'Hello Special Characters', self.consolidate_auth)
        self.special_characters_wiki = self.project.get_wiki_page(SPECIAL_CHARACTERS_ALLOWED)
        assert_in(to_mongo_key(SPECIAL_CHARACTERS_ALLOWED), self.project.wiki_pages_current)
        url = self.project.api_url_for(
            'project_wiki_delete',
            wname=SPECIAL_CHARACTERS_ALLOWED
        )
        self.app.delete(
            url,
            auth=self.auth
        )
        self.project.reload()
        assert_not_in(to_mongo_key(SPECIAL_CHARACTERS_ALLOWED), self.project.wiki_pages_current)
    def test_POST_register_embargo_does_not_make_project_or_children_public(self, mock_enqueue):
        public_project = ProjectFactory(creator=self.user, is_public=True)
        component = NodeFactory(creator=self.user, parent=public_project, title="Component", is_public=True)
        subproject = ProjectFactory(creator=self.user, parent=public_project, title="Subproject", is_public=True)
        subproject_component = NodeFactory(creator=self.user, parent=subproject, title="Subcomponent", is_public=True)
        res = self.app.post(
            public_project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"),
            self.valid_embargo_payload,
            content_type="application/json",
            auth=self.user.auth,
        )
        public_project.reload()
        assert_equal(res.status_code, 201)

        # Last node directly registered from self.project
        registration = Node.load(public_project.node__registrations[-1])

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        assert_true(registration.is_pending_embargo_for_existing_registration)
        assert_is_not_none(registration.embargo)

        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)
示例#8
0
 def test_rmap_post_non_public_project_should_error(self):
     private_project = ProjectFactory(creator=self.user, is_public=False)
     url = private_project.api_url_for('node_rmap_post')
     res = self.app.post_json(url, {},
                              auth=self.user.auth,
                              expect_errors=True)
     assert_equal(res.status_code, 400)
 def test_get_most_in_common_contributors(self):
     # project 1 (contrib 1, contrib 2, unreg_contrib 3)
     #  - component 1 (contrib 1)
     # project 2 - add should show contrib 1 first (2 links), contrib 2 second (1 link)
     contributor_1 = AuthUserFactory()
     contributor_2 = AuthUserFactory()
     self.project.add_contributor(contributor_1, auth=self.auth)
     self.project.add_contributor(contributor_2, auth=self.auth)
     # has one unregistered contributor
     self.project.add_unregistered_contributor(
         fullname=fake.name(),
         email=fake.email(),
         auth=self.auth,
     )
     self.project.save()
     component = NodeFactory(parent=self.project, creator=self.user)
     component.add_contributor(contributor_1, auth=self.auth)
     component.save()
     project_2 = ProjectFactory(creator=self.user)
     project_2.add_contributor(contributor_1, auth=self.auth)
     url = project_2.api_url_for('get_most_in_common_contributors')
     res = self.app.get(url, auth=self.user.auth)
     project_2.reload()
     res_contribs = res.json['contributors']
     assert_equal(len(res.json['contributors']), 2)
     assert_equal(contributor_1._id, res_contribs[0]['id'])
     assert_equal(res_contribs[0]['n_projects_in_common'], 2)
     assert_equal(contributor_2._id, res_contribs[1]['id'])
     assert_equal(res_contribs[1]['n_projects_in_common'], 1)
示例#10
0
class TestGoogleDriveHgridViews(OsfTestCase):

    def setUp(self):
        super(TestGoogleDriveHgridViews, self).setUp()
        self.user = AuthUserFactory()
        self.user.add_addon('googledrive')
        self.project = ProjectFactory(creator=self.user)
        self.project.add_addon('googledrive', Auth(self.user))
        self.node_settings = self.project.get_addon('googledrive')
        self.user_settings = self.user.get_addon('googledrive')
        self.node_settings.user_settings = self.user_settings
        self.user_settings.save()
        self.node_settings.save()
        # Log user in
        self.app.authenticate(*self.user.auth)

    @mock.patch('website.addons.googledrive.views.hgrid.GoogleDriveClient.folders')
    def test_googledrive_folders(self, mock_drive_client_folders):
        folderId = '12345'
        mock_drive_client_folders.return_value = mock_folders['items']
        url = api_url_for('googledrive_folders', pid=self.project._primary_key, folderId=folderId)
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json), len(mock_folders['items']))

    @mock.patch('website.addons.googledrive.views.hgrid.GoogleDriveClient.about')
    def test_googledrive_folders_returns_only_root(self, mock_about):
        mock_about.return_value = {'rootFolderId': '24601'}

        url = self.project.api_url_for('googledrive_folders')
        res = self.app.get(url, auth=self.user.auth)

        assert_equal(len(res.json), 1)
        assert_equal(res.status_code, 200)
        assert_equal(res.json[0]['id'], '24601')
示例#11
0
class TestCreateBucket(OsfTestCase):

    def setUp(self):

        super(TestCreateBucket, 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()

    def test_bad_names(self):
        assert_false(validate_bucket_name('bogus naMe'))
        assert_false(validate_bucket_name(''))
        assert_false(validate_bucket_name('no'))
        assert_false(validate_bucket_name('.cantstartwithp'))
        assert_false(validate_bucket_name('or.endwith.'))
        assert_false(validate_bucket_name('..nodoubles'))
        assert_false(validate_bucket_name('no_unders_in'))

    def test_names(self):
        assert_true(validate_bucket_name('imagoodname'))
        assert_true(validate_bucket_name('still.passing'))
        assert_true(validate_bucket_name('can-have-dashes'))
        assert_true(validate_bucket_name('kinda.name.spaced'))

    @mock.patch('website.addons.s3.views.crud.create_bucket')
    @mock.patch('website.addons.s3.utils.get_bucket_drop_down')
    def test_create_bucket_pass(self, mock_make, mock_dropdown):
        mock_make.return_value = True
        mock_dropdown.return_value = ['mybucket']
        url = self.project.api_url_for('create_new_bucket')
        ret = self.app.post_json(url, {'bucket_name': 'doesntevenmatter'}, auth=self.user.auth)

        assert_equals(ret.status_int, http.OK)

    @mock.patch('website.addons.s3.views.crud.create_bucket')
    def test_create_bucket_fail(self, mock_make):
        error = S3ResponseError(418, 'because Im a test')
        error.message = 'This should work'
        mock_make.side_effect = error

        url = "/api/v1/project/{0}/s3/newbucket/".format(self.project._id)
        ret = self.app.post_json(url, {'bucket_name': 'doesntevenmatter'}, auth=self.user.auth, expect_errors=True)

        assert_equals(ret.body, '{"message": "This should work", "title": "Problem connecting to S3"}')
示例#12
0
class TestGoogleDriveHgridViews(OsfTestCase):

    def setUp(self):
        super(TestGoogleDriveHgridViews, self).setUp()
        self.user = AuthUserFactory()
        self.user.add_addon('googledrive')
        self.project = ProjectFactory(creator=self.user)
        self.project.add_addon('googledrive', Auth(self.user))
        self.node_settings = self.project.get_addon('googledrive')
        self.user_settings = self.user.get_addon('googledrive')
        self.node_settings.user_settings = self.user_settings
        self.user_settings.save()
        self.node_settings.save()
        # Log user in
        self.app.authenticate(*self.user.auth)

    @mock.patch('website.addons.googledrive.views.hgrid.GoogleDriveClient.folders')
    def test_googledrive_folders(self, mock_drive_client_folders):
        folderId = '12345'
        mock_drive_client_folders.return_value = mock_folders['items']
        url = api_url_for('googledrive_folders', pid=self.project._primary_key, folderId=folderId)
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json), len(mock_folders['items']))

    @mock.patch('website.addons.googledrive.views.hgrid.GoogleDriveClient.about')
    def test_googledrive_folders_returns_only_root(self, mock_about):
        mock_about.return_value = {'rootFolderId': '24601'}

        url = self.project.api_url_for('googledrive_folders')
        res = self.app.get(url, auth=self.user.auth)

        assert_equal(len(res.json), 1)
        assert_equal(res.status_code, 200)
        assert_equal(res.json[0]['id'], '24601')
 def test_get_most_in_common_contributors(self):
     # project 1 (contrib 1, contrib 2, unreg_contrib 3)
     #  - component 1 (contrib 1)
     # project 2 - add should show contrib 1 first (2 links), contrib 2 second (1 link)
     contributor_1 = AuthUserFactory()
     contributor_2 = AuthUserFactory()
     self.project.add_contributor(contributor_1, auth=self.auth)
     self.project.add_contributor(contributor_2, auth=self.auth)
     # has one unregistered contributor
     self.project.add_unregistered_contributor(
         fullname=fake.name(),
         email=fake.email(),
         auth=self.auth,
     )
     self.project.save()
     component = NodeFactory(parent=self.project, creator=self.user)
     component.add_contributor(contributor_1, auth=self.auth)
     component.save()
     project_2 = ProjectFactory(creator=self.user)
     project_2.add_contributor(contributor_1, auth=self.auth)
     url = project_2.api_url_for('get_most_in_common_contributors')
     res = self.app.get(url, auth=self.user.auth)
     project_2.reload()
     res_contribs = res.json['contributors']
     assert_equal(len(res.json['contributors']), 2)
     assert_equal(contributor_1._id, res_contribs[0]['id'])
     assert_equal(res_contribs[0]['n_projects_in_common'], 2)
     assert_equal(contributor_2._id, res_contribs[1]['id'])
     assert_equal(res_contribs[1]['n_projects_in_common'], 1)
示例#14
0
class TestCreateBucket(OsfTestCase):

    def setUp(self):

        super(TestCreateBucket, 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()

    def test_bad_names(self):
        assert_false(validate_bucket_name('bogus naMe'))
        assert_false(validate_bucket_name(''))
        assert_false(validate_bucket_name('no'))
        assert_false(validate_bucket_name('.cantstartwithp'))
        assert_false(validate_bucket_name('or.endwith.'))
        assert_false(validate_bucket_name('..nodoubles'))
        assert_false(validate_bucket_name('no_unders_in'))

    def test_names(self):
        assert_true(validate_bucket_name('imagoodname'))
        assert_true(validate_bucket_name('still.passing'))
        assert_true(validate_bucket_name('can-have-dashes'))
        assert_true(validate_bucket_name('kinda.name.spaced'))

    @mock.patch('website.addons.s3.views.crud.create_bucket')
    @mock.patch('website.addons.s3.utils.get_bucket_drop_down')
    def test_create_bucket_pass(self, mock_make, mock_dropdown):
        mock_make.return_value = True
        mock_dropdown.return_value = ['mybucket']
        url = self.project.api_url_for('create_new_bucket')
        ret = self.app.post_json(url, {'bucket_name': 'doesntevenmatter'}, auth=self.user.auth)

        assert_equals(ret.status_int, http.OK)

    @mock.patch('website.addons.s3.views.crud.create_bucket')
    def test_create_bucket_fail(self, mock_make):
        error = S3ResponseError(418, 'because Im a test')
        error.message = 'This should work'
        mock_make.side_effect = error

        url = "/api/v1/project/{0}/s3/newbucket/".format(self.project._id)
        ret = self.app.post_json(url, {'bucket_name': 'doesntevenmatter'}, auth=self.user.auth, expect_errors=True)

        assert_equals(ret.body, '{"message": "This should work", "title": "Problem connecting to S3"}')
示例#15
0
    def test_POST_register_embargo_does_not_make_project_or_children_public(
            self, mock_enqueue):
        public_project = ProjectFactory(creator=self.user, is_public=True)
        component = NodeFactory(creator=self.user,
                                parent=public_project,
                                title='Component',
                                is_public=True)
        subproject = ProjectFactory(creator=self.user,
                                    parent=public_project,
                                    title='Subproject',
                                    is_public=True)
        subproject_component = NodeFactory(creator=self.user,
                                           parent=subproject,
                                           title='Subcomponent',
                                           is_public=True)
        res = self.app.post(public_project.api_url_for(
            'node_register_template_page_post',
            template=u'Open-Ended_Registration'),
                            self.valid_embargo_payload,
                            content_type='application/json',
                            auth=self.user.auth)
        public_project.reload()
        assert_equal(res.status_code, 201)

        # Last node directly registered from self.project
        registration = Node.load(public_project.node__registrations[-1])

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        assert_true(registration.is_pending_embargo_for_existing_registration)
        assert_is_not_none(registration.embargo)

        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)
示例#16
0
 def test_cannot_rename_wiki_page_to_home(self):
     user = AuthUserFactory()
     # A fresh project where the 'home' wiki page has no content
     project = ProjectFactory(creator=user)
     project.update_node_wiki('Hello', 'hello world', Auth(user=user))
     url = project.api_url_for('project_wiki_rename', wname=to_mongo_key('Hello'))
     res = self.app.put_json(url, {'value': 'home'}, auth=user.auth, expect_errors=True)
     assert_equal(res.status_code, 409)
示例#17
0
 def test_cannot_rename_wiki_page_to_home(self):
     user = AuthUserFactory()
     # A fresh project where the 'home' wiki page has no content
     project = ProjectFactory(creator=user)
     project.update_node_wiki('Hello', 'hello world', Auth(user=user))
     url = project.api_url_for('project_wiki_rename', wname=to_mongo_key('Hello'))
     res = self.app.put_json(url, {'value': 'home'}, auth=user.auth, expect_errors=True)
     assert_equal(res.status_code, 409)
示例#18
0
class RegistrationsTestBase(OsfTestCase):
    def setUp(self):
        super(RegistrationsTestBase, self).setUp()

        self.user = AuthUserFactory()
        self.auth = Auth(self.user)
        self.node = ProjectFactory(creator=self.user)
        self.non_admin = AuthUserFactory()
        self.node.add_contributor(
            self.non_admin,
            permissions.DEFAULT_CONTRIBUTOR_PERMISSIONS,
            auth=self.auth,
            save=True
        )
        self.non_contrib = AuthUserFactory()

        MetaSchema.remove()
        ensure_schemas()
        self.meta_schema = MetaSchema.find_one(
            Q('name', 'eq', 'Open-Ended Registration') &
            Q('schema_version', 'eq', 2)
        )
        self.draft = DraftRegistrationFactory(
            initiator=self.user,
            branched_from=self.node,
            registration_schema=self.meta_schema,
            registration_metadata={
                'summary': {'value': 'Some airy'}
            }
        )

        current_month = dt.datetime.now().strftime("%B")
        current_year = dt.datetime.now().strftime("%Y")

        valid_date = dt.datetime.now() + dt.timedelta(days=180)
        self.embargo_payload = {
            u'embargoEndDate': unicode(valid_date.strftime('%a, %d, %B %Y %H:%M:%S')) + u' GMT',
            u'registrationChoice': 'embargo'
        }
        self.invalid_embargo_date_payload = {
            u'embargoEndDate': u"Thu, 01 {month} {year} 05:00:00 GMT".format(
                month=current_month,
                year=str(int(current_year) - 1)
            ),
            u'registrationChoice': 'embargo'
        }
        self.immediate_payload = {
            'registrationChoice': 'immediate'
        }
        self.invalid_payload = {
            'registrationChoice': 'foobar'
        }

    def draft_url(self, view_name):
        return self.node.web_url_for(view_name, draft_id=self.draft._id)

    def draft_api_url(self, view_name):
        return self.node.api_url_for(view_name, draft_id=self.draft._id)
示例#19
0
    def test_import_auth_invalid_account(self):
        ea = self.ExternalAccountFactory()

        node = ProjectFactory(creator=self.user)
        node.add_addon(self.ADDON_SHORT_NAME, auth=self.auth)
        node.save()
        url = node.api_url_for("{0}_import_auth".format(self.ADDON_SHORT_NAME))
        res = self.app.put_json(url, {"external_account_id": ea._id}, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, http.FORBIDDEN)
示例#20
0
 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)
示例#21
0
class TestCommentViews(OsfTestCase):
    def setUp(self):
        super(TestCommentViews, self).setUp()
        self.project = ProjectFactory(is_public=True)
        self.user = AuthUserFactory()
        self.project.add_contributor(self.user)
        self.project.save()
        self.user.save()

    def test_view_project_comments_updates_user_comments_view_timestamp(self):
        url = self.project.api_url_for("update_comments_timestamp")
        res = self.app.put_json(url, {"page": "node", "rootId": self.project._id}, auth=self.user.auth)
        self.user.reload()

        user_timestamp = self.user.comments_viewed_timestamp[self.project._id]
        view_timestamp = dt.datetime.utcnow()
        assert_datetime_equal(user_timestamp, view_timestamp)

    def test_confirm_non_contrib_viewers_dont_have_pid_in_comments_view_timestamp(self):
        non_contributor = AuthUserFactory()
        url = self.project.api_url_for("update_comments_timestamp")
        res = self.app.put_json(url, {"page": "node", "rootId": self.project._id}, auth=self.user.auth)

        non_contributor.reload()
        assert_not_in(self.project._id, non_contributor.comments_viewed_timestamp)

    def test_view_comments_updates_user_comments_view_timestamp_files(self):
        osfstorage = self.project.get_addon("osfstorage")
        root_node = osfstorage.get_root()
        test_file = root_node.append_file("test_file")
        test_file.create_version(
            self.user,
            {"object": "06d80e", "service": "cloud", osfstorage_settings.WATERBUTLER_RESOURCE: "osf"},
            {"size": 1337, "contentType": "img/png"},
        ).save()

        url = self.project.api_url_for("update_comments_timestamp")
        res = self.app.put_json(url, {"page": "files", "rootId": test_file._id}, auth=self.user.auth)
        self.user.reload()

        user_timestamp = self.user.comments_viewed_timestamp[test_file._id]
        view_timestamp = dt.datetime.utcnow()
        assert_datetime_equal(user_timestamp, view_timestamp)
示例#22
0
 def test_build_dropbox_urls_file(self):
     node = ProjectFactory()
     fake_metadata = mock_responses['metadata_single']
     result = utils.build_dropbox_urls(fake_metadata, node)
     path = utils.clean_path(fake_metadata['path'])
     assert_equal(result['download'],
                  node.web_url_for('dropbox_download', path=path))
     assert_equal(result['view'],
                  node.web_url_for('dropbox_view_file', path=path))
     assert_equal(result['delete'],
                  node.api_url_for('dropbox_delete_file', path=path))
示例#23
0
    def test_import_auth_invalid_account(self):
        ea = self.ExternalAccountFactory()

        node = ProjectFactory(creator=self.user)
        node.add_addon(self.ADDON_SHORT_NAME, auth=self.auth)
        node.save()
        url = node.api_url_for('{0}_import_auth'.format(self.ADDON_SHORT_NAME))
        res = self.app.put_json(url, {'external_account_id': ea._id},
                                auth=self.user.auth,
                                expect_errors=True)
        assert_equal(res.status_code, http.FORBIDDEN)
示例#24
0
class TestViewHelpers(OsfTestCase):

    def setUp(self):
        super(TestViewHelpers, self).setUp()
        self.project = ProjectFactory()
        self.wname = 'New page'
        self.project.update_node_wiki(self.wname, 'some content', Auth(self.project.creator))

    def test_get_wiki_web_urls(self):
        urls = _get_wiki_web_urls(self.project, self.wname)
        assert_equal(urls['base'], self.project.web_url_for('project_wiki_home', _guid=True))
        assert_equal(urls['edit'], self.project.web_url_for('project_wiki_view', wname=self.wname, _guid=True))
        assert_equal(urls['home'], self.project.web_url_for('project_wiki_home', _guid=True))
        assert_equal(urls['page'], self.project.web_url_for('project_wiki_view', wname=self.wname, _guid=True))

    def test_get_wiki_api_urls(self):
        urls = _get_wiki_api_urls(self.project, self.wname)
        assert_equal(urls['base'], self.project.api_url_for('project_wiki_home'))
        assert_equal(urls['delete'], self.project.api_url_for('project_wiki_delete', wname=self.wname))
        assert_equal(urls['rename'], self.project.api_url_for('project_wiki_rename', wname=self.wname))
        assert_equal(urls['content'], self.project.api_url_for('wiki_page_content', wname=self.wname))
示例#25
0
class TestViewHelpers(OsfTestCase):

    def setUp(self):
        super(TestViewHelpers, self).setUp()
        self.project = ProjectFactory()
        self.wname = 'New page'
        self.project.update_node_wiki(self.wname, 'some content', Auth(self.project.creator))

    def test_get_wiki_web_urls(self):
        urls = _get_wiki_web_urls(self.project, self.wname)
        assert_equal(urls['base'], self.project.web_url_for('project_wiki_home', _guid=True))
        assert_equal(urls['edit'], self.project.web_url_for('project_wiki_view', wname=self.wname, _guid=True))
        assert_equal(urls['home'], self.project.web_url_for('project_wiki_home', _guid=True))
        assert_equal(urls['page'], self.project.web_url_for('project_wiki_view', wname=self.wname, _guid=True))

    def test_get_wiki_api_urls(self):
        urls = _get_wiki_api_urls(self.project, self.wname)
        assert_equal(urls['base'], self.project.api_url_for('project_wiki_home'))
        assert_equal(urls['delete'], self.project.api_url_for('project_wiki_delete', wname=self.wname))
        assert_equal(urls['rename'], self.project.api_url_for('project_wiki_rename', wname=self.wname))
        assert_equal(urls['content'], self.project.api_url_for('wiki_page_content', wname=self.wname))
示例#26
0
    def test_import_auth_cant_write_node(self):
        ea = self.ExternalAccountFactory()
        user = AuthUserFactory()
        user.add_addon(self.ADDON_SHORT_NAME, auth=Auth(user))
        user.external_accounts.append(ea)
        user.save()

        node = ProjectFactory(creator=self.user)
        node.add_contributor(user, permissions=[permissions.READ], auth=self.auth, save=True)
        node.add_addon(self.ADDON_SHORT_NAME, auth=self.auth)
        node.save()
        url = node.api_url_for("{0}_import_auth".format(self.ADDON_SHORT_NAME))
        res = self.app.put_json(url, {"external_account_id": ea._id}, auth=user.auth, expect_errors=True)
        assert_equal(res.status_code, http.FORBIDDEN)
示例#27
0
 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.test_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)
示例#28
0
 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.test_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)
示例#29
0
    def test_import_auth_cant_write_node(self):
        ea = self.ExternalAccountFactory()
        user = AuthUserFactory()
        user.add_addon(self.ADDON_SHORT_NAME, auth=Auth(user))
        user.external_accounts.append(ea)
        user.save()

        node = ProjectFactory(creator=self.user)
        node.add_contributor(user, permissions=[permissions.READ], auth=self.auth, save=True)
        node.add_addon(self.ADDON_SHORT_NAME, auth=self.auth)
        node.save()
        url = node.api_url_for('{0}_import_auth'.format(self.ADDON_SHORT_NAME))
        res = self.app.put_json(url, {
            'external_account_id': ea._id
        }, auth=user.auth, expect_errors=True)
        assert_equal(res.status_code, http.FORBIDDEN)
示例#30
0
 def test_build_dropbox_urls_file(self):
     node = ProjectFactory()
     fake_metadata = mock_responses['metadata_single']
     result = utils.build_dropbox_urls(fake_metadata, node)
     path = utils.clean_path(fake_metadata['path'])
     assert_equal(
         result['download'],
         node.web_url_for('dropbox_download', path=path)
     )
     assert_equal(
         result['view'],
         node.web_url_for('dropbox_view_file', path=path)
     )
     assert_equal(
         result['delete'],
         node.api_url_for('dropbox_delete_file', path=path)
     )
示例#31
0
    def test_find_unread_includes_edited_comments(self):
        project = ProjectFactory()
        user = AuthUserFactory()
        project.add_contributor(user)
        project.save()
        comment = CommentFactory(node=project, user=project.creator)

        url = project.api_url_for('update_comments_timestamp')
        payload = {'page': 'node', 'rootId': project._id}
        res = self.app.put_json(url, payload, auth=user.auth)
        user.reload()
        n_unread = Comment.find_n_unread(user=user, node=project)
        assert_equal(n_unread, 0)

        # Edit previously read comment
        comment.edit(auth=Auth(project.creator), content='edited', save=True)
        n_unread = Comment.find_n_unread(user=user, node=project)
        assert_equal(n_unread, 1)
示例#32
0
    def test_import_auth(self):
        ea = self.ExternalAccountFactory()
        self.user.external_accounts.append(ea)
        self.user.save()

        node = ProjectFactory(creator=self.user)
        node_settings = node.get_or_add_addon(self.ADDON_SHORT_NAME, auth=Auth(self.user))
        node.save()
        url = node.api_url_for("{0}_import_auth".format(self.ADDON_SHORT_NAME))
        res = self.app.put_json(url, {"external_account_id": ea._id}, auth=self.user.auth)
        assert_equal(res.status_code, http.OK)
        assert_in("result", res.json)
        node_settings.reload()
        assert_equal(node_settings.external_account._id, ea._id)

        node.reload()
        last_log = node.logs[-1]
        assert_equal(last_log.action, "{0}_node_authorized".format(self.ADDON_SHORT_NAME))
示例#33
0
    def test_find_unread_includes_edited_comments(self):
        project = ProjectFactory()
        user = AuthUserFactory()
        project.add_contributor(user)
        project.save()
        comment = CommentFactory(node=project, user=project.creator)

        url = project.api_url_for("update_comments_timestamp")
        payload = {"page": "node", "rootId": project._id}
        res = self.app.put_json(url, payload, auth=user.auth)
        user.reload()
        n_unread = Comment.find_n_unread(user=user, node=project, page="node")
        assert_equal(n_unread, 0)

        # Edit previously read comment
        comment.edit(auth=Auth(project.creator), content="edited", save=True)
        n_unread = Comment.find_n_unread(user=user, node=project, page="node")
        assert_equal(n_unread, 1)
示例#34
0
    def test_import_auth(self):
        ea = self.ExternalAccountFactory()
        self.user.external_accounts.append(ea)
        self.user.save()

        node = ProjectFactory(creator=self.user)
        node_settings = node.get_or_add_addon(self.ADDON_SHORT_NAME, auth=Auth(self.user))
        node.save()
        url = node.api_url_for('{0}_import_auth'.format(self.ADDON_SHORT_NAME))
        res = self.app.put_json(url, {
            'external_account_id': ea._id
        }, auth=self.user.auth)
        assert_equal(res.status_code, http.OK)
        assert_in('result', res.json)
        node_settings.reload()
        assert_equal(node_settings.external_account._id, ea._id)

        node.reload()
        last_log = node.logs.latest()
        assert_equal(last_log.action, '{0}_node_authorized'.format(self.ADDON_SHORT_NAME))
    def test_POST_register_make_public_immediately_creates_private_pending_registration_for_public_project(self, mock_enqueue):
        public_project = ProjectFactory(is_public=True, creator=self.user)
        component = NodeFactory(
            creator=self.user,
            parent=public_project,
            title='Component',
            is_public=True
        )
        subproject = ProjectFactory(
            creator=self.user,
            parent=public_project,
            title='Subproject',
            is_public=True
        )
        subproject_component = NodeFactory(
            creator=self.user,
            parent=subproject,
            title='Subcomponent',
            is_public=True
        )
        res = self.app.post(
            public_project.api_url_for('node_register_template_page_post', template=u'Open-Ended_Registration'),
            self.valid_make_public_payload,
            content_type='application/json',
            auth=self.user.auth
        )
        public_project.reload()
        assert_equal(res.status_code, 201)
        assert_equal(res.json['urls']['registrations'], public_project.web_url_for('node_registrations'))

        # Last node directly registered from self.project
        registration = Node.load(public_project.node__registrations[-1])

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)
示例#36
0
class TestGoogleDriveAuthViews(OsfTestCase):

    def setUp(self):
        super(TestGoogleDriveAuthViews, self).setUp()
        self.user = AuthUserFactory()
        self.user.add_addon('googledrive')
        self.project = ProjectFactory(creator=self.user)
        self.project.add_addon('googledrive', Auth(self.user))
        self.node_settings = self.project.get_addon('googledrive')
        self.user_settings = self.user.get_addon('googledrive')
        oauth_settings = GoogleDriveOAuthSettingsFactory()
        self.user_settings.oauth_settings = oauth_settings
        self.node_settings.user_settings = self.user_settings
        # Log user in
        self.app.authenticate(*self.user.auth)
        self.flow = mock.Mock()
        self.credentials = mock.Mock()

    # Class variables(self) are usually used to mark mock variables. Can be removed later.
    @mock.patch('website.addons.googledrive.views.auth.GoogleAuthClient.start')
    def test_googledrive_oauth_start(self, mock_auth_client_start):
        url = api_url_for('googledrive_oauth_start_user', Auth(self.user))
        authorization_url = 'https://fake.domain/'
        state = 'secure state'
        mock_auth_client_start.return_value = (authorization_url, state)
        res = self.app.post(url)
        assert_true(res.json['url'], authorization_url)

    @mock.patch('website.addons.googledrive.views.auth.GoogleAuthClient.userinfo')
    @mock.patch('website.addons.googledrive.views.auth.GoogleAuthClient.finish')
    @mock.patch('website.addons.googledrive.views.auth.session')
    def test_googledrive_oauth_finish(self, mock_session, mock_auth_client_finish, mock_auth_client_userinfo):
        user_no_addon = AuthUserFactory()
        nid = self.project._primary_key
        state = '1234'
        mock_session.data = {
            'googledrive_auth_nid': nid,
            'googledrive_auth_state': state,
        }
        mock_auth_client_finish.return_value = {
            'access_token': '1111',
            'refresh_token': '2222',
            'expires_at': time.time() + 3600,
        }
        mock_auth_client_userinfo.return_value = {
            'sub': 'unique id',
            'name': 'test-user',
        }
        url = api_url_for('googledrive_oauth_finish', user_no_addon.auth, nid=self.project._primary_key, code='1234', state=state)
        res = self.app.get(url)
        assert_is_redirect(res)

    @mock.patch('website.addons.googledrive.views.auth.flash')
    def test_googledrive_oauth_finish_cancelled(self, mock_flash):
        user_no_addon = AuthUserFactory()
        url = api_url_for(
            'googledrive_oauth_finish',
            user_no_addon.auth,
            nid=self.project._primary_key,
            code='1234',
            state='3322',
            error='User declined!'
        )
        res = self.app.get(url)
        assert_is_redirect(res)
        mock_flash.assert_called_once()

    @mock.patch('website.addons.googledrive.views.auth.GoogleAuthClient.userinfo')
    @mock.patch('website.addons.googledrive.views.auth.GoogleAuthClient.finish')
    @mock.patch('website.addons.googledrive.views.auth.session')
    def test_googledrive_oauth_finish_user_only(self, mock_session, mock_auth_client_finish, mock_auth_client_userinfo):
        user_no_addon = AuthUserFactory()
        state = '1234'
        mock_session.data = {
            'googledrive_auth_state': state,
        }
        mock_auth_client_finish.return_value = {
            'access_token': '1111',
            'refresh_token': '2222',
            'expires_at': time.time() + 3600,
        }
        mock_auth_client_userinfo.return_value = {
            'sub': 'unique id',
            'name': 'test-user',
        }
        url = api_url_for('googledrive_oauth_finish', user_no_addon.auth, code='1234', state=state)
        res = self.app.get(url)
        assert_is_redirect(res)

    @mock.patch('website.addons.googledrive.views.auth.GoogleAuthClient.revoke')
    def test_googledrive_oauth_delete_user(self, mock_auth_client_revoke):
        self.user_settings.access_token = 'abc123'
        self.user_settings.save()
        assert_true(self.user_settings.has_auth)
        self.user.save()
        url = api_url_for('googledrive_oauth_delete_user')
        self.app.delete(url)
        self.user_settings.reload()
        mock_auth_client_revoke.assert_called_once()
        assert_false(self.user_settings.has_auth)

    def test_googledrive_deauthorize(self):
        self.node_settings.folder_id = 'foobar'
        self.node_settings.folder_path = 'My folder'
        self.node_settings.save()

        url = self.project.api_url_for('googledrive_deauthorize')

        self.app.delete(url)
        self.project.reload()
        self.node_settings.reload()

        assert_false(self.node_settings.has_auth)
        assert_is(self.node_settings.folder_id, None)
        assert_is(self.node_settings.folder_path, None)
        assert_is(self.node_settings.user_settings, None)
示例#37
0
class TestGoogleDriveConfigViews(OsfTestCase):

    def setUp(self):
        super(TestGoogleDriveConfigViews, self).setUp()
        self.user = AuthUserFactory()
        self.user.add_addon('googledrive')
        self.user_settings = self.user.get_addon('googledrive')
        self.project = ProjectFactory(creator=self.user)
        self.project.add_addon('googledrive', Auth(self.user))
        self.node_settings = self.project.get_addon('googledrive')
        self.node_settings.user_settings = self.user_settings
        oauth_settings = GoogleDriveOAuthSettingsFactory()
        oauth_settings.save()
        self.user_settings.oauth_settings = oauth_settings
        self.node_settings.save()
        # Log user in
        self.app.authenticate(*self.user.auth)

    def test_drive_user_config_get_returns_correct_urls(self):
        self.user.add_addon('googledrive')
        url = api_url_for('googledrive_user_config_get', Auth(self.user))
        res = self.app.get(url)
        assert_equal(res.status_code, 200)
        result = res.json['result']['urls']
        assert_true(result['create'], api_url_for('googledrive_oauth_start_user'))
        assert_true(result['delete'], api_url_for('googledrive_oauth_delete_user'))

    def test_drive_user_config_get_has_auth(self):
        self.user.add_addon('googledrive')
        user_settings = self.user.get_addon('googledrive')
        user_settings.access_token = 'abc123'
        user_settings.save()
        url = api_url_for('googledrive_user_config_get', Auth(self.user))
        res = self.app.get(url)
        assert_equal(res.status_code, 200)
        result = res.json['result']
        assert_true(result['userHasAuth'])

    def test_drive_user_config_get_not_has_auth(self):
        self.user_settings.access_token = None
        self.user_settings.save()
        url = api_url_for('googledrive_user_config_get', Auth(self.user))
        res = self.app.get(url)
        assert_equal(res.status_code, 200)
        result = res.json['result']
        assert_false(result['userHasAuth'])

    # TODO
    def test_googledrive_config_put(self):
        url = self.project.api_url_for('googledrive_config_put')
        selected = {
            'path': 'Google Drive/ My Folder',
            'name': 'Google Drive/ My Folder',
            'id': '12345'
        }
        # Can set folder through API call
        res = self.app.put_json(url, {'selected': selected}, auth=self.user.auth)

        assert_equal(res.status_code, 200)
        self.node_settings.reload()
        self.project.reload()

        # Folder was set
        assert_equal(self.node_settings.folder_name, ' My Folder')
        # A log event was created
        last_log = self.project.logs[-1]
        assert_equal(last_log.action, 'googledrive_folder_selected')
        params = last_log.params
        assert_equal(params['folder'], self.node_settings.folder_name)
示例#38
0
class RegistrationEmbargoViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationEmbargoViewsTestCase, self).setUp()
        ensure_schemas()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        self.registration = RegistrationFactory(project=self.project,
                                                creator=self.user)

        current_month = datetime.datetime.now().strftime("%B")
        current_year = datetime.datetime.now().strftime("%Y")

        self.valid_make_public_payload = json.dumps({
            u'embargoEndDate':
            u'Fri, 01, {month} {year} 00:00:00 GMT'.format(month=current_month,
                                                           year=current_year),
            u'registrationChoice':
            'immediate',
            u'summary':
            unicode(fake.sentence())
        })
        valid_date = datetime.datetime.now() + datetime.timedelta(days=180)
        self.valid_embargo_payload = json.dumps({
            u'embargoEndDate':
            unicode(valid_date.strftime('%a, %d, %B %Y %H:%M:%S')) + u' GMT',
            u'registrationChoice':
            'embargo',
            u'summary':
            unicode(fake.sentence())
        })
        self.invalid_embargo_date_payload = json.dumps({
            u'embargoEndDate':
            u"Thu, 01 {month} {year} 05:00:00 GMT".format(
                month=current_month, year=str(int(current_year) - 1)),
            u'registrationChoice':
            'embargo',
            u'summary':
            unicode(fake.sentence())
        })

    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_register_make_public_immediately_creates_registration_approval(
            self, mock_enqueue):
        res = self.app.post(self.project.api_url_for(
            'node_register_template_page_post',
            template=u'Open-Ended_Registration'),
                            self.valid_make_public_payload,
                            content_type='application/json',
                            auth=self.user.auth)
        assert_equal(res.status_code, 201)

        registration = Node.find().sort('-registered_date')[0]

        assert_true(registration.is_registration)
        assert_not_equal(registration.registration_approval, None)

    # Regression test for https://openscience.atlassian.net/browse/OSF-5039
    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_register_make_public_immediately_creates_private_pending_registration_for_public_project(
            self, mock_enqueue):
        public_project = ProjectFactory(is_public=True, creator=self.user)
        component = NodeFactory(creator=self.user,
                                parent=public_project,
                                title='Component',
                                is_public=True)
        subproject = ProjectFactory(creator=self.user,
                                    parent=public_project,
                                    title='Subproject',
                                    is_public=True)
        subproject_component = NodeFactory(creator=self.user,
                                           parent=subproject,
                                           title='Subcomponent',
                                           is_public=True)
        res = self.app.post(public_project.api_url_for(
            'node_register_template_page_post',
            template=u'Open-Ended_Registration'),
                            self.valid_make_public_payload,
                            content_type='application/json',
                            auth=self.user.auth)
        public_project.reload()
        assert_equal(res.status_code, 201)

        # Last node directly registered from self.project
        registration = Node.load(public_project.node__registrations[-1])

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_register_make_public_does_not_make_children_public(
            self, mock_enqueue):
        component = NodeFactory(creator=self.user,
                                parent=self.project,
                                title='Component')
        subproject = ProjectFactory(creator=self.user,
                                    parent=self.project,
                                    title='Subproject')
        subproject_component = NodeFactory(creator=self.user,
                                           parent=subproject,
                                           title='Subcomponent')

        res = self.app.post(self.project.api_url_for(
            'node_register_template_page_post',
            template=u'Open-Ended_Registration'),
                            self.valid_make_public_payload,
                            content_type='application/json',
                            auth=self.user.auth)
        self.project.reload()
        # Last node directly registered from self.project
        registration = Node.load(self.project.node__registrations[-1])
        assert_false(registration.is_public)
        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_register_embargo_is_not_public(self, mock_enqueue):
        res = self.app.post(self.project.api_url_for(
            'node_register_template_page_post',
            template=u'Open-Ended_Registration'),
                            self.valid_embargo_payload,
                            content_type='application/json',
                            auth=self.user.auth)

        assert_equal(res.status_code, 201)

        registration = Node.find().sort('-registered_date')[0]

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        assert_true(registration.is_pending_embargo_for_existing_registration)
        assert_is_not_none(registration.embargo)

    # Regression test for https://openscience.atlassian.net/browse/OSF-5071
    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_register_embargo_does_not_make_project_or_children_public(
            self, mock_enqueue):
        public_project = ProjectFactory(creator=self.user, is_public=True)
        component = NodeFactory(creator=self.user,
                                parent=public_project,
                                title='Component',
                                is_public=True)
        subproject = ProjectFactory(creator=self.user,
                                    parent=public_project,
                                    title='Subproject',
                                    is_public=True)
        subproject_component = NodeFactory(creator=self.user,
                                           parent=subproject,
                                           title='Subcomponent',
                                           is_public=True)
        res = self.app.post(public_project.api_url_for(
            'node_register_template_page_post',
            template=u'Open-Ended_Registration'),
                            self.valid_embargo_payload,
                            content_type='application/json',
                            auth=self.user.auth)
        public_project.reload()
        assert_equal(res.status_code, 201)

        # Last node directly registered from self.project
        registration = Node.load(public_project.node__registrations[-1])

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        assert_true(registration.is_pending_embargo_for_existing_registration)
        assert_is_not_none(registration.embargo)

        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_invalid_embargo_end_date_returns_HTTPBad_Request(
            self, mock_enqueue):
        res = self.app.post(self.project.api_url_for(
            'node_register_template_page_post',
            template=u'Open-Ended_Registration'),
                            self.invalid_embargo_date_payload,
                            content_type='application/json',
                            auth=self.user.auth,
                            expect_errors=True)

        assert_equal(res.status_code, 400)

    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_valid_POST_embargo_adds_to_parent_projects_log(
            self, mock_enquque):
        initial_project_logs = len(self.project.logs)
        res = self.app.post(self.project.api_url_for(
            'node_register_template_page_post',
            template=u'Open-Ended_Registration'),
                            self.valid_embargo_payload,
                            content_type='application/json',
                            auth=self.user.auth)
        self.project.reload()
        # Logs: Created, registered, embargo initiated
        assert_equal(len(self.project.logs), initial_project_logs + 1)

    def test_non_contributor_GET_approval_returns_HTTPError(self):
        non_contributor = AuthUserFactory()
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[
            self.user._id]['approval_token']
        approval_url = self.registration.web_url_for('view_project',
                                                     token=approval_token)

        res = self.app.get(approval_url,
                           auth=non_contributor.auth,
                           expect_errors=True)
        assert_equal(http.FORBIDDEN, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

    def test_non_contributor_GET_disapproval_returns_HTTPError(self):
        non_contributor = AuthUserFactory()
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[
            self.user._id]['rejection_token']
        approval_url = self.registration.web_url_for('view_project',
                                                     token=rejection_token)

        res = self.app.get(approval_url,
                           auth=non_contributor.auth,
                           expect_errors=True)
        assert_equal(http.FORBIDDEN, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)
示例#39
0
class TestAddonLogs(OsfTestCase):
    def setUp(self):
        super(TestAddonLogs, self).setUp()
        self.flask_app = SetEnvironMiddleware(self.app.app,
                                              REMOTE_ADDR='127.0.0.1')
        self.test_app = webtest.TestApp(self.flask_app)
        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 = AddonGitHubOauthSettings(github_user_id='john')
        self.oauth_settings.save()
        self.user_addon.oauth_settings = self.oauth_settings
        self.user_addon.oauth_access_token = 'secret'
        self.user_addon.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.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.test_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.test_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.test_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.test_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.test_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.test_app.put_json(url,
                               payload,
                               headers={'Content-Type': 'application/json'})
        self.node.reload()

        assert_equal(
            self.node.logs[-1].action,
            'github_addon_file_renamed',
        )
示例#40
0
class TestWikiRename(OsfTestCase):
    def setUp(self):
        super(TestWikiRename, self).setUp()

        self.project = ProjectFactory(is_public=True)
        api_key = ApiKeyFactory()
        self.project.creator.api_keys.append(api_key)
        self.project.creator.save()
        self.consolidate_auth = Auth(user=self.project.creator,
                                     api_key=api_key)
        self.auth = ('test', api_key._primary_key)
        self.project.update_node_wiki('home', 'Hello world',
                                      self.consolidate_auth)

        self.page_name = 'page2'
        self.project.update_node_wiki(self.page_name, 'content',
                                      self.consolidate_auth)
        self.project.save()
        self.page = self.project.get_wiki_page(self.page_name)

        self.wiki = self.project.get_wiki_page('home')
        self.url = self.project.api_url_for(
            'project_wiki_rename',
            wname=self.page_name,
        )

    def test_rename_wiki_page_valid(self, new_name=u'away'):
        self.app.put_json(self.url, {'value': new_name}, auth=self.auth)
        self.project.reload()

        old_wiki = self.project.get_wiki_page(self.page_name)
        assert_false(old_wiki)

        new_wiki = self.project.get_wiki_page(new_name)
        assert_true(new_wiki)
        assert_equal(new_wiki._primary_key, self.page._primary_key)
        assert_equal(new_wiki.content, self.page.content)
        assert_equal(new_wiki.version, self.page.version)

    def test_rename_wiki_page_invalid(self, new_name=u'invalid/name'):
        res = self.app.put_json(
            self.url,
            {'value': new_name},
            auth=self.auth,
            expect_errors=True,
        )
        assert_equal(http.BAD_REQUEST, res.status_code)
        assert_equal(res.json['message_short'], 'Invalid name')
        assert_equal(res.json['message_long'],
                     'Page name cannot contain forward slashes.')
        self.project.reload()
        old_wiki = self.project.get_wiki_page(self.page_name)
        assert_true(old_wiki)

    def test_rename_wiki_page_duplicate(self):
        self.project.update_node_wiki('away', 'Hello world',
                                      self.consolidate_auth)
        new_name = 'away'
        res = self.app.put_json(
            self.url,
            {'value': new_name},
            auth=self.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 409)

    def test_rename_wiki_name_not_found(self):
        url = self.project.api_url_for('project_wiki_rename',
                                       wname='not_found_page_name')
        res = self.app.put_json(url, {'value': 'new name'},
                                auth=self.auth,
                                expect_errors=True)
        assert_equal(res.status_code, 404)

    def test_cannot_rename_wiki_page_to_home(self):
        user = AuthUserFactory()
        # A fresh project where the 'home' wiki page has no content
        project = ProjectFactory(creator=user)
        project.update_node_wiki('Hello', 'hello world', Auth(user=user))
        url = project.api_url_for('project_wiki_rename',
                                  wname=to_mongo_key('Hello'))
        res = self.app.put_json(url, {'value': 'home'},
                                auth=user.auth,
                                expect_errors=True)
        assert_equal(res.status_code, 409)

    def test_rename_wiki_name_with_value_missing(self):
        # value is missing
        res = self.app.put_json(self.url, {},
                                auth=self.auth,
                                expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_rename_wiki_page_duplicate_different_casing(self):
        # attempt to rename 'page2' from setup to different case of 'away'.
        old_name = 'away'
        new_name = 'AwAy'
        self.project.update_node_wiki(old_name, 'Hello world',
                                      self.consolidate_auth)
        res = self.app.put_json(self.url, {'value': new_name},
                                auth=self.auth,
                                expect_errors=True)
        assert_equal(res.status_code, 409)

    def test_rename_wiki_page_same_name_different_casing(self):
        old_name = 'away'
        new_name = 'AWAY'
        self.project.update_node_wiki(old_name, 'Hello world',
                                      self.consolidate_auth)
        url = self.project.api_url_for('project_wiki_rename', wname=old_name)
        res = self.app.put_json(url, {'value': new_name},
                                auth=self.auth,
                                expect_errors=False)
        assert_equal(res.status_code, 200)

    def test_cannot_rename_home_page(self):
        url = self.project.api_url_for('project_wiki_rename', wname='home')
        res = self.app.put_json(url, {'value': 'homelol'},
                                auth=self.auth,
                                expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_can_rename_to_a_deleted_page(self):
        self.project.delete_node_wiki(self.page_name, self.consolidate_auth)
        self.project.save()

        # Creates a new page
        self.project.update_node_wiki('page3', 'moarcontent',
                                      self.consolidate_auth)
        self.project.save()

        # Renames the wiki to the deleted page
        url = self.project.api_url_for('project_wiki_rename', wname='page3')
        res = self.app.put_json(url, {'value': self.page_name}, auth=self.auth)
        assert_equal(res.status_code, 200)

    def test_rename_wiki_page_with_valid_html(self):
        # script is not an issue since data is sanitized via bleach or mako before display.
        self.test_rename_wiki_page_valid(new_name=u'<html>hello<html>')

    def test_rename_wiki_page_with_invalid_html(self):
        # script is not an issue since data is sanitized via bleach or mako before display.
        # with that said routes still do not accept forward slashes
        self.test_rename_wiki_page_invalid(new_name=u'<html>hello</html>')

    def test_rename_wiki_page_with_non_ascii_title(self):
        self.test_rename_wiki_page_valid(new_name=u'øˆ∆´ƒøßå√ß')

    def test_rename_wiki_page_with_valid_special_character_title(self):
        self.test_rename_wiki_page_valid(new_name=SPECIAL_CHARACTERS_ALLOWED)

    def test_rename_wiki_page_with_invalid_special_character_title(self):
        self.test_rename_wiki_page_invalid(new_name=SPECIAL_CHARACTERS_ALL)
示例#41
0
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)
示例#42
0
class TestAddonAuth(OsfTestCase):

    def setUp(self):
        super(TestAddonAuth, self).setUp()
        self.flask_app = SetEnvironMiddleware(self.app.app, REMOTE_ADDR='127.0.0.1')
        self.test_app = webtest.TestApp(self.flask_app)
        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 = AddonGitHubOauthSettings(github_user_id='john')
        self.oauth_settings.save()
        self.user_addon.oauth_settings = self.oauth_settings
        self.user_addon.oauth_access_token = 'secret'
        self.user_addon.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.save()

    def build_url(self, **kwargs):
        options = dict(
            action='download',
            cookie=self.cookie,
            nid=self.node._id,
            provider=self.node_addon.config.short_name,
        )
        options.update(kwargs)
        return api_url_for('get_auth', **options)

    def test_auth_download(self):
        url = self.build_url()
        res = self.test_app.get(url)
        assert_equal(res.json['auth'], views.make_auth(self.user))
        assert_equal(res.json['credentials'], self.node_addon.serialize_waterbutler_credentials())
        assert_equal(res.json['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(res.json['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.test_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[::-1])
        res = self.test_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.test_app.get(url, expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_auth_bad_ip(self):
        flask_app = SetEnvironMiddleware(self.app.app, REMOTE_ADDR='192.168.1.1')
        test_app = webtest.TestApp(flask_app)
        url = self.build_url()
        res = test_app.get(url, expect_errors=True)
        assert_equal(res.status_code, 403)
示例#43
0
class MendeleyViewsTestCase(OsfTestCase):

    def setUp(self):
        super(MendeleyViewsTestCase, self).setUp()
        self.account = MendeleyAccountFactory()
        self.user = AuthUserFactory(external_accounts=[self.account])
        self.account.display_name = self.user.fullname
        self.account.save()
        self.user_addon = MendeleyUserSettingsFactory(owner=self.user, external_account=self.account)
        self.project = ProjectFactory(creator=self.user)
        self.node_addon = MendeleyNodeSettingsFactory(owner=self.project)
        self.node_addon.set_auth(external_account=self.account, user=self.user)
        #self.user_addon.grant_oauth_access(self.node_addon, self.account, metadata={'lists': 'list'})
        self.node = MockNode()
        self.node.addon = self.node_addon
        self.id_patcher = mock.patch('website.addons.mendeley.model.Mendeley.client_id')
        self.secret_patcher = mock.patch('website.addons.mendeley.model.Mendeley.client_secret')
        self.id_patcher.__get__ = mock.Mock(return_value='1234567890asdf')
        self.secret_patcher.__get__ = mock.Mock(return_value='1234567890asdf')
        self.id_patcher.start()
        self.secret_patcher.start()

    def tearDown(self):
        self.id_patcher.stop()
        self.secret_patcher.stop()

    def test_serialize_settings_authorizer(self):
        #"""dict: a serialized version of user-specific addon settings"""
        res = self.app.get(
            self.project.api_url_for('mendeley_get_config'),
            auth=self.user.auth,
        )
        result = res.json['result']
        assert_true(result['nodeHasAuth'])
        assert_true(result['userHasAuth'])
        assert_true(result['userIsOwner'])
        assert_equal(result['folder'], {'name': ''})
        assert_equal(result['ownerName'], self.user.fullname)
        assert_true(result['urls']['auth'])
        assert_true(result['urls']['config'])
        assert_true(result['urls']['deauthorize'])
        assert_true(result['urls']['folders'])
        assert_true(result['urls']['importAuth'])
        assert_true(result['urls']['settings'])

    def test_serialize_settings_non_authorizer(self):
        #"""dict: a serialized version of user-specific addon settings"""
        non_authorizing_user = AuthUserFactory()
        self.project.add_contributor(non_authorizing_user, save=True)
        res = self.app.get(
            self.project.api_url_for('mendeley_get_config'),
            auth=non_authorizing_user.auth,
        )
        result = res.json['result']
        assert_true(result['nodeHasAuth'])
        assert_false(result['userHasAuth'])
        assert_false(result['userIsOwner'])
        assert_equal(result['folder'], {'name': ''})
        assert_equal(result['ownerName'], self.user.fullname)
        assert_true(result['urls']['auth'])
        assert_true(result['urls']['config'])
        assert_true(result['urls']['deauthorize'])
        assert_true(result['urls']['folders'])
        assert_true(result['urls']['importAuth'])
        assert_true(result['urls']['settings'])

    def test_set_auth(self):

        res = self.app.put_json(
            self.project.api_url_for('mendeley_add_user_auth'),
            {
                'external_account_id': self.account._id,
            },
            auth=self.user.auth,
        )

        assert_equal(
            res.status_code,
            200
        )

        assert_true(res.json['result']['userHasAuth'])

        assert_equal(
            self.node_addon.user_settings,
            self.user_addon
        )
        assert_equal(
            self.node_addon.external_account,
            self.account
        )

    def test_remove_user_auth(self):
        self.node_addon.set_auth(self.account, self.user)

        res = self.app.delete_json(
            self.project.api_url_for('mendeley_remove_user_auth'),
            {
                'external_account_id': self.account._id,
            },
            auth=self.user.auth,
        )

        assert_equal(
            res.status_code,
            200
        )

        self.node_addon.reload()

        assert_is_none(self.node_addon.user_settings)
        assert_is_none(self.node_addon.external_account)

    @mock.patch('website.addons.mendeley.model.Mendeley._folder_metadata')
    def test_set_config_owner(self, mock_metadata):
        mock_metadata.return_value = MockFolder(name='Fake Folder')
        # Settings config updates node settings
        self.node_addon.associated_user_settings = []
        self.node_addon.save()
        res = self.app.put_json(
            self.project.api_url_for('mendeley_set_config'),
            {
                'external_account_id': self.account._id,
                'external_list_id': 'list',
            },
            auth=self.user.auth,
        )
        self.node_addon.reload()
        assert_equal(self.user_addon, self.node_addon.user_settings)
        serializer = MendeleySerializer(node_settings=self.node_addon, user_settings=self.user_addon)
        expected = {
            'result': serializer.serialized_node_settings
        }
        assert_equal(res.json, expected)

    @mock.patch('website.addons.mendeley.model.Mendeley._folder_metadata')
    def test_set_config_not_owner(self, mock_metadata):
        mock_metadata.return_value = MockFolder(name='Fake Folder')
        user = AuthUserFactory()
        user.add_addon('mendeley')
        self.project.add_contributor(user)
        self.project.save()
        res = self.app.put_json(
            self.project.api_url_for('mendeley_set_config'),
            {
                'external_account_id': self.account._id,
                'external_list_id': 'list',
            },
            auth=user.auth,
        )
        self.node_addon.reload()
        assert_equal(self.user_addon, self.node_addon.user_settings)
        serializer = MendeleySerializer(node_settings=self.node_addon, user_settings=None)
        expected = {
            'result': serializer.serialized_node_settings
        }
        assert_equal(res.json, expected)

    def test_mendeley_widget_view_complete(self):
        # JSON: everything a widget needs
        assert_false(self.node_addon.complete)
        assert_equal(self.node_addon.mendeley_list_id, None)
        self.node_addon.set_target_folder('ROOT-ID', 'ROOT', auth=Auth(user=self.user))
        res = views.mendeley_widget(node_addon=self.node_addon,
                                    project=self.project,
                                    node=self.node,
                                    nid=self.node_addon._id,
                                    pid=self.project._id,
                                    auth=self.user.auth)
        assert_true(res['complete'])
        assert_equal(res['list_id'], 'ROOT-ID')

    def test_widget_view_incomplete(self):
        # JSON: tell the widget when it hasn't been configured
        assert_false(self.node_addon.complete)
        assert_equal(self.node_addon.mendeley_list_id, None)
        res = views.mendeley_widget(node_addon=self.node_addon,
                                    project=self.project,
                                    node=self.node,
                                    nid=self.node_addon._id,
                                    pid=self.project._id,
                                    auth=self.user.auth)
        assert_false(res['complete'])
        assert_is_none(res['list_id'])

    @httpretty.activate
    def test_mendeley_citation_list_root(self):

        httpretty.register_uri(
            httpretty.GET,
            urlparse.urljoin(API_URL, 'folders'),
            body=mock_responses['folders'],
            content_type='application/json'
        )

        res = self.app.get(
            self.project.api_url_for('mendeley_citation_list'),
            auth=self.user.auth
        )
        root = res.json['contents'][0]
        assert_equal(root['kind'], 'folder')
        assert_equal(root['id'], 'ROOT')
        assert_equal(root['parent_list_id'], '__')

    @httpretty.activate
    def test_mendeley_citation_list_non_root(self):

        httpretty.register_uri(
            httpretty.GET,
            urlparse.urljoin(API_URL, 'folders'),
            body=mock_responses['folders'],
            content_type='application/json'
        )

        httpretty.register_uri(
            httpretty.GET,
            urlparse.urljoin(API_URL, 'documents'),
            body=mock_responses['documents'],
            content_type='application/json'
        )

        res = self.app.get(
            self.project.api_url_for('mendeley_citation_list', mendeley_list_id='ROOT'),
            auth=self.user.auth
        )

        children = res.json['contents']
        assert_equal(len(children), 7)
        assert_equal(children[0]['kind'], 'folder')
        assert_equal(children[1]['kind'], 'file')
        assert_true(children[1].get('csl') is not None)

    @httpretty.activate
    def test_mendeley_citation_list_non_linked_or_child_non_authorizer(self):

        non_authorizing_user = AuthUserFactory()
        self.project.add_contributor(non_authorizing_user, save=True)

        self.node_addon.mendeley_list_id = 'e843da05-8818-47c2-8c37-41eebfc4fe3f'
        self.node_addon.save()

        httpretty.register_uri(
            httpretty.GET,
            urlparse.urljoin(API_URL, 'folders'),
            body=mock_responses['folders'],
            content_type='application/json'
        )

        httpretty.register_uri(
            httpretty.GET,
            urlparse.urljoin(API_URL, 'documents'),
            body=mock_responses['documents'],
            content_type='application/json'
        )

        res = self.app.get(
            self.project.api_url_for('mendeley_citation_list', mendeley_list_id='ROOT'),
            auth=non_authorizing_user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 403)
示例#44
0
class TestAddonLogs(OsfTestCase):

    def setUp(self):
        super(TestAddonLogs, self).setUp()
        self.flask_app = SetEnvironMiddleware(self.app.app, REMOTE_ADDR='127.0.0.1')
        self.test_app = webtest.TestApp(self.flask_app)
        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 = AddonGitHubOauthSettings(github_user_id='john')
        self.oauth_settings.save()
        self.user_addon.oauth_settings = self.oauth_settings
        self.user_addon.oauth_access_token = 'secret'
        self.user_addon.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.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,
        }

    def test_add_log(self):
        path = 'pizza'
        url = self.node.api_url_for('create_waterbutler_log')
        payload = self.build_payload(metadata={'path': path})
        nlogs = len(self.node.logs)
        self.test_app.put_json(url, payload, headers={'Content-Type': 'application/json'})
        self.node.reload()
        assert_equal(len(self.node.logs), nlogs + 1)

    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.test_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.test_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.test_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.test_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)
示例#45
0
class TestAddonAuth(OsfTestCase):

    def setUp(self):
        super(TestAddonAuth, self).setUp()
        self.flask_app = SetEnvironMiddleware(self.app.app, REMOTE_ADDR='127.0.0.1')
        self.test_app = webtest.TestApp(self.flask_app)
        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 = AddonGitHubOauthSettings(github_user_id='john')
        self.oauth_settings.save()
        self.user_addon.oauth_settings = self.oauth_settings
        self.user_addon.oauth_access_token = 'secret'
        self.user_addon.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.save()

    def build_url(self, **kwargs):
        options = dict(
            action='download',
            cookie=self.cookie,
            nid=self.node._id,
            provider=self.node_addon.config.short_name,
        )
        options.update(kwargs)
        return api_url_for('get_auth', **options)

    def test_auth_download(self):
        url = self.build_url()
        res = self.test_app.get(url)
        assert_equal(res.json['auth'], views.make_auth(self.user))
        assert_equal(res.json['credentials'], self.node_addon.serialize_waterbutler_credentials())
        assert_equal(res.json['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(res.json['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.test_app.get(url, expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_auth_bad_cookie(self):
        url = self.build_url(cookie=self.cookie[::-1])
        res = self.test_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.test_app.get(url, expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_auth_bad_ip(self):
        flask_app = SetEnvironMiddleware(self.app.app, REMOTE_ADDR='192.168.1.1')
        test_app = webtest.TestApp(flask_app)
        url = self.build_url()
        res = test_app.get(url, expect_errors=True)
        assert_equal(res.status_code, 403)
示例#46
0
class TestAddonFileViews(OsfTestCase):

    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 = AddonGitHubOauthSettings(
            github_user_id='denbarell',
            oauth_access_token='Truthy'
        )

        self.oauth.save()

        self.user_addon.oauth_settings = self.oauth
        self.user_addon.save()

        self.node_addon.user_settings = self.user_addon
        self.node_addon.save()

        # self.node_addon.user_settings = 'Truthy'
        # setattr(self.node_addon, 'has_auth', True)

    def get_mako_return(self):
        ret = serialize_node(self.project, Auth(self.user), primary=True)
        ret.update({
            'extra': '',
            'provider': '',
            'rendered': '',
            'file_path': '',
            'files_url': '',
            'file_name': '',
            'render_url': '',
        })
        ret.update(rubeus.collect_addon_assets(self.project))
        return ret

    def test_redirects_to_guid(self):
        path = 'bigdata'
        guid, _ = self.node_addon.find_or_create_file_guid('/' + path)

        resp = self.app.get(
            self.project.web_url_for(
                'addon_view_or_download_file',
                path=path,
                provider='github'
            ),
            auth=self.user.auth
        )

        assert_equals(resp.status_code, 302)
        assert_equals(resp.headers['Location'], 'http://*****:*****@mock.patch('website.addons.base.request')
    def test_public_download_url_includes_view_only(self, mock_request):
        view_only = 'justworkplease'
        mock_request.args = {
            'view_only': view_only
        }

        path = 'cloudfiles'
        guid, _ = self.node_addon.find_or_create_file_guid('/' + path)

        assert_in('view_only={}'.format(view_only), guid.public_download_url)

    @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()

        path = 'cloudfiles'
        mock_view_file.return_value = self.get_mako_return()
        guid, _ = self.node_addon.find_or_create_file_guid('/' + path)

        self.app.get(guid.guid_url + '?action=view', auth=self.user.auth)

        args, kwargs = mock_view_file.call_args
        assert_equals(kwargs, {})
        assert_equals(args[-1], {'action': 'view'})
        assert_equals(args[1], self.project)
        assert_equals(args[0].user, self.user)
        assert_equals(args[2], self.node_addon)

    @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()

        path = 'cloudfiles'
        mock_view_file.return_value = self.get_mako_return()
        guid, _ = self.node_addon.find_or_create_file_guid('/' + path)

        self.app.get(guid.guid_url, auth=self.user.auth)

        args, kwargs = mock_view_file.call_args
        assert_equals(kwargs, {})
        assert_equals(args[-1], {})
        assert_equals(args[1], self.project)
        assert_equals(args[0].user, self.user)
        assert_equals(args[2], self.node_addon)

    def test_download_create_guid(self):
        path = 'cloudfiles'

        self.app.get(
            self.project.web_url_for(
                'addon_view_or_download_file',
                path=path,
                provider='github',
                action='download'
            ),
            auth=self.user.auth
        )

        guid, created = self.node_addon.find_or_create_file_guid('/' + path)

        assert_true(guid)
        assert_false(created)
        assert_equals(guid.waterbutler_path, '/' + path)

    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, 403)

    def test_head_returns_url(self):
        path = 'the little engine that couldnt'
        guid, _ = self.node_addon.find_or_create_file_guid('/' + path)

        download_url = furl.furl(guid.download_url)
        download_url.args['accept_url'] = 'false'

        resp = self.app.head(guid.guid_url, auth=self.user.auth)

        assert_urls_equal(resp.headers['Location'], download_url.url)

    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.api_url_for(
                'addon_render_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.api_url_for(
                'addon_render_file',
                path=path,
                provider='github',
                action='download'
            ),
            auth=self.user.auth,
            expect_errors=True
        )

        assert_equals(resp.status_code, 401)

    def test_unconfigured_addons_raise(self):
        path = 'cloudfiles'
        self.node_addon.repo = None
        self.node_addon.save()

        resp = self.app.get(
            self.project.api_url_for(
                'addon_render_file',
                path=path,
                provider='github',
                action='download'
            ),
            auth=self.user.auth,
            expect_errors=True
        )

        assert_equals(resp.status_code, 400)
示例#47
0
class TestViewsConfig(OsfTestCase):

    def setUp(self):

        super(TestViewsConfig, 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 = 'FIGSHARE_TITLE'
        self.node_settings.save()

        self.figshare = create_mock_figshare('test')

    def configure_responses(self):
        httpretty.register_uri(
            httpretty.GET,
            join_path(self.node_settings.api_url, 'articles'),
            body=dumps(self.figshare.articles.return_value)
        )
        httpretty.register_uri(
            httpretty.GET,
            join_path(self.node_settings.api_url, 'articles', '902210'),
            body=dumps(self.figshare.article.return_value)
        )

    @httpretty.activate
    def test_import_auth(self):
        self.configure_responses()
        """Testing figshare_import_user_auth to ensure that auth gets imported correctly"""
        settings = self.node_settings
        settings.user_settings = None
        settings.save()
        url = '/api/v1/project/{0}/figshare/config/import-auth/'.format(self.project._id)
        self.app.put(url, auth=self.user.auth)
        self.node_settings.reload()
        assert_is_not_none(settings.user_settings)

    def test_cancelled_oauth_request_from_user_settings_page_redirects_correctly(self):
        res = self.app.get(api_url_for('figshare_oauth_callback', uid=self.user._id), auth=self.user.auth)
        assert_equal(res.status_code, 302)
        assert_urls_equal(res.headers['location'], web_url_for('user_addons'))

    def test_cancelled_oauth_request_from_node_settings_page_redirects_correctly(self):
        res = self.app.get(api_url_for('figshare_oauth_callback', uid=self.user._id, nid=self.project._id), auth=self.user.auth)
        assert_equal(res.status_code, 302)
        assert_urls_equal(res.headers['location'], self.project.web_url_for('node_setting'))

    def test_deauthorize(self):
        """Testing figshare_deauthorize to ensure user auth gets removed from
        the node and that the AddonNodeSettings are cleared

        """
        settings = self.node_settings
        url = '/api/v1/project/{0}/figshare/config/'.format(self.project._id)
        self.app.delete(url, auth=self.user.auth)
        self.node_settings.reload()
        assert_true(settings.user_settings is None)
        is_none = (
            settings.figshare_id is None and settings.figshare_title is None and settings.figshare_type is None
        )
        assert_true(is_none)

    def test_config_no_change(self):
        nlogs = len(self.project.logs)
        url = self.project.api_url_for('figshare_config_put')
        rv = self.app.put_json(
            url,
            {
                'selected': {
                    'id': '123456',
                    'name': 'FIGSHARE_TITLE',
                    'type': 'project',
                },
            },
            auth=self.user.auth,
        )
        self.project.reload()
        assert_equal(rv.status_int, http.OK)
        assert_equal(len(self.project.logs), nlogs)

    def test_config_change(self):
        nlogs = len(self.project.logs)
        url = self.project.api_url_for('figshare_config_put')
        rv = self.app.put_json(
            url,
            {
                'selected': {
                    'id': 'project_9001',
                    'name': 'IchangedbecauseIcan',
                    'type': 'project'
                },
            },
            auth=self.user.auth,
        )
        self.project.reload()
        self.node_settings.reload()

        assert_equal(rv.status_int, http.OK)
        assert_equal(self.node_settings.figshare_id, 'project_9001')
        assert_equal(self.node_settings.figshare_title, 'IchangedbecauseIcan')
        assert_equal(len(self.project.logs), nlogs + 1)
        assert_equal(
            self.project.logs[nlogs].action,
            'figshare_content_linked'
        )

    def test_config_change_invalid(self):
        nlogs = len(self.project.logs)
        url = self.project.api_url_for('figshare_config_put')
        rv = self.app.put_json(
            url,
            {
                'selected': {
                    'type': 'project'
                },
            },
            auth=self.user.auth,
            expect_errors=True,
        )
        self.project.reload()
        self.node_settings.reload()

        assert_equal(rv.status_int, http.BAD_REQUEST)
        assert_equal(len(self.project.logs), nlogs)

    def test_config_change_not_owner(self):
        user2 = AuthUserFactory()
        self.project.add_contributor(user2, save=True)
        nlogs = len(self.project.logs)
        url = self.project.api_url_for('figshare_config_put')
        res = self.app.put_json(
            url,
            {},
            auth=user2.auth,
            expect_errors=True,
        )
        self.project.reload()
        assert_equal(res.status_int, http.FORBIDDEN)
        assert_equal(nlogs, len(self.project.logs))

    @httpretty.activate
    def test_serialize_settings_helper_returns_correct_auth_info(self):
        self.configure_responses()

        result = serialize_settings(self.node_settings, self.user, client=figshare_mock)
        assert_equal(result['nodeHasAuth'], self.node_settings.has_auth)
        assert_true(result['userHasAuth'])
        assert_true(result['userIsOwner'])

    @httpretty.activate
    def test_serialize_settings_for_user_no_auth(self):
        self.configure_responses()

        no_addon_user = AuthUserFactory()
        result = serialize_settings(self.node_settings, no_addon_user, client=figshare_mock)
        assert_false(result['userIsOwner'])
        assert_false(result['userHasAuth'])
示例#48
0
class TestWikiViews(OsfTestCase):
    def setUp(self):
        super(TestWikiViews, self).setUp()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(is_public=True, creator=self.user)
        self.consolidate_auth = Auth(user=self.project.creator)

    def test_wiki_url_get_returns_200(self):
        url = self.project.web_url_for('project_wiki_page', wname='home')
        res = self.app.get(url)
        assert_equal(res.status_code, 200)

    def test_wiki_url_for_pointer_returns_200(self):
        # TODO: explain how this tests a pointer
        project = ProjectFactory(is_public=True)
        self.project.add_pointer(project,
                                 Auth(self.project.creator),
                                 save=True)
        url = self.project.web_url_for('project_wiki_page', wname='home')
        res = self.app.get(url)
        assert_equal(res.status_code, 200)

    def test_wiki_content_returns_200(self):
        node = ProjectFactory(is_public=True)
        url = node.api_url_for('wiki_page_content', wname='somerandomid')
        res = self.app.get(url)
        assert_equal(res.status_code, 200)

    def test_wiki_url_for_component_returns_200(self):
        component = NodeFactory(project=self.project, is_public=True)
        url = component.web_url_for('project_wiki_page', wname='home')
        res = self.app.get(url)
        assert_equal(res.status_code, 200)

    def test_serialize_wiki_toc(self):
        project = ProjectFactory()
        auth = Auth(project.creator)
        NodeFactory(project=project, creator=project.creator)
        no_wiki = NodeFactory(project=project, creator=project.creator)
        project.save()

        serialized = _serialize_wiki_toc(project, auth=auth)
        assert_equal(len(serialized), 2)
        no_wiki.delete_addon('wiki', auth=auth)
        serialized = _serialize_wiki_toc(project, auth=auth)
        assert_equal(len(serialized), 1)

    def test_get_wiki_url_pointer_component(self):
        """Regression test for issues
        https://github.com/CenterForOpenScience/osf/issues/363 and
        https://github.com/CenterForOpenScience/openscienceframework.org/issues/574

        """
        user = UserFactory()
        pointed_node = NodeFactory(creator=user)
        project = ProjectFactory(creator=user)
        auth = Auth(user=user)
        project.add_pointer(pointed_node, auth=auth, save=True)

        serialized = _serialize_wiki_toc(project, auth)
        assert_equal(
            serialized[0]['url'],
            pointed_node.web_url_for('project_wiki_page',
                                     wname='home',
                                     _guid=True))

    def test_project_wiki_edit_post(self):
        self.project.update_node_wiki('home',
                                      content='old content',
                                      auth=Auth(self.project.creator))
        url = self.project.web_url_for('project_wiki_edit_post', wname='home')
        res = self.app.post(url, {
            'content': 'new content'
        },
                            auth=self.user.auth).follow()
        assert_equal(res.status_code, 200)
        self.project.reload()
        # page was updated with new content
        new_wiki = self.project.get_wiki_page('home')
        assert_equal(new_wiki.content, 'new content')

    def test_project_wiki_edit_post_with_new_wname_and_no_content(self):
        page_name = fake.catch_phrase()

        old_wiki_page_count = NodeWikiPage.find().count()
        url = self.project.web_url_for('project_wiki_edit_post',
                                       wname=page_name)
        # User submits to edit form with no content
        res = self.app.post(url, {'content': ''}, auth=self.user.auth).follow()
        assert_equal(res.status_code, 200)

        new_wiki_page_count = NodeWikiPage.find().count()
        # A new wiki page was created in the db
        assert_equal(new_wiki_page_count, old_wiki_page_count + 1)

        # Node now has the new wiki page associated with it
        self.project.reload()
        new_page = self.project.get_wiki_page(page_name)
        assert_is_not_none(new_page)

    def test_project_wiki_edit_post_with_new_wname_and_content(self):
        page_name, page_content = fake.catch_phrase(), fake.bs()

        old_wiki_page_count = NodeWikiPage.find().count()
        url = self.project.web_url_for('project_wiki_edit_post',
                                       wname=page_name)
        # User submits to edit form with no content
        res = self.app.post(url, {
            'content': page_content
        },
                            auth=self.user.auth).follow()
        assert_equal(res.status_code, 200)

        new_wiki_page_count = NodeWikiPage.find().count()
        # A new wiki page was created in the db
        assert_equal(new_wiki_page_count, old_wiki_page_count + 1)

        # Node now has the new wiki page associated with it
        self.project.reload()
        new_page = self.project.get_wiki_page(page_name)
        assert_is_not_none(new_page)
        # content was set
        assert_equal(new_page.content, page_content)

    def test_project_wiki_edit_post_with_non_ascii_title(self):
        # regression test for https://github.com/CenterForOpenScience/openscienceframework.org/issues/1040
        # wname doesn't exist in the db, so it will be created
        new_wname = u'øˆ∆´ƒøßå√ß'
        url = self.project.web_url_for('project_wiki_edit_post',
                                       wname=new_wname)
        res = self.app.post(url, {
            'content': 'new content'
        },
                            auth=self.user.auth).follow()
        assert_equal(res.status_code, 200)
        self.project.reload()
        wiki = self.project.get_wiki_page(new_wname)
        assert_equal(wiki.page_name, new_wname)

        # updating content should return correct url as well.
        res = self.app.post(url, {
            'content': 'updated content'
        },
                            auth=self.user.auth).follow()
        assert_equal(res.status_code, 200)

    def test_project_wiki_edit_post_with_special_characters(self):
        new_wname = 'title: ' + SPECIAL_CHARACTERS_ALLOWED
        new_wiki_content = 'content: ' + SPECIAL_CHARACTERS_ALL
        url = self.project.web_url_for('project_wiki_edit_post',
                                       wname=new_wname)
        res = self.app.post(url, {
            'content': new_wiki_content
        },
                            auth=self.user.auth).follow()
        assert_equal(res.status_code, 200)
        self.project.reload()
        wiki = self.project.get_wiki_page(new_wname)
        assert_equal(wiki.page_name, new_wname)
        assert_equal(wiki.content, new_wiki_content)
        assert_equal(res.status_code, 200)

    def test_wiki_edit_get_home(self):
        url = self.project.web_url_for('project_wiki_edit', wname='home')
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)

    def test_project_wiki_compare_returns_200(self):
        self.project.update_node_wiki('home', 'updated content',
                                      Auth(self.user))
        self.project.save()
        url = self.project.web_url_for('project_wiki_compare',
                                       wname='home',
                                       wver=1)
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)

    def test_project_wiki_compare_with_invalid_wname(self):
        url = self.project.web_url_for('project_wiki_compare',
                                       wname='this-doesnt-exist',
                                       wver=1)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 404)

    def test_wiki_page_creation_strips_whitespace(self):
        # Regression test for:
        # https://github.com/CenterForOpenScience/openscienceframework.org/issues/1080
        # wname has a trailing space
        url = self.project.web_url_for('project_wiki_edit', wname='cupcake ')
        res = self.app.post(url, {
            'content': 'blah'
        }, auth=self.user.auth).follow()
        assert_equal(res.status_code, 200)

        self.project.reload()
        wiki = self.project.get_wiki_page('cupcake')
        assert_is_not_none(wiki)

    def test_wiki_validate_name(self):
        url = self.project.api_url_for('project_wiki_validate_name',
                                       wname='Capslock')
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)

    def test_wiki_validate_name_cannot_create_home(self):
        url = self.project.api_url_for('project_wiki_validate_name',
                                       wname='home')
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 409)

    def test_project_wiki_validate_name_mixed_casing(self):
        url = self.project.api_url_for('project_wiki_validate_name',
                                       wname='CaPsLoCk')
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_not_in('capslock', self.project.wiki_pages_current)
        self.project.update_node_wiki('CaPsLoCk', 'hello',
                                      self.consolidate_auth)
        assert_in('capslock', self.project.wiki_pages_current)

    def test_project_wiki_validate_name_diplay_correct_capitalization(self):
        url = self.project.api_url_for('project_wiki_validate_name',
                                       wname='CaPsLoCk')
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_in('CaPsLoCk', res)

    def test_project_wiki_validate_name_conflict_different_casing(self):
        url = self.project.api_url_for('project_wiki_validate_name',
                                       wname='CAPSLOCK')
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        self.project.update_node_wiki('CaPsLoCk', 'hello',
                                      self.consolidate_auth)
        assert_in('capslock', self.project.wiki_pages_current)
        url = self.project.api_url_for('project_wiki_validate_name',
                                       wname='capslock')
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 409)

    def test_project_dashboard_shows_no_wiki_content_text(self):
        # Regression test for:
        # https://github.com/CenterForOpenScience/openscienceframework.org/issues/1104
        project = ProjectFactory(creator=self.user)
        url = project.web_url_for('view_project')
        res = self.app.get(url, auth=self.user.auth)
        assert_in('No wiki content', res)

    def test_project_dashboard_wiki_wname_get_shows_non_ascii_characters(self):
        # Regression test for:
        # https://github.com/CenterForOpenScience/openscienceframework.org/issues/1104
        text = u'你好'
        self.project.update_node_wiki('home', text, Auth(self.user))

        # can view wiki preview from project dashboard
        url = self.project.web_url_for('view_project')
        res = self.app.get(url, auth=self.user.auth)
        assert_in(text, res)

    def test_project_wiki_home_api_route(self):
        url = self.project.api_url_for('project_wiki_home')
        res = self.app.get(url, auth=self.user.auth)
        assert_equals(res.status_code, 302)
        # TODO: should this route exist? it redirects you to the web_url_for, not api_url_for.
        # page_url = self.project.api_url_for('project_wiki_page', wname='home')
        # assert_in(page_url, res.location)

    def test_project_wiki_home_web_route(self):
        page_url = self.project.web_url_for('project_wiki_page',
                                            wname='home',
                                            _guid=True)
        url = self.project.web_url_for('project_wiki_home')
        res = self.app.get(url, auth=self.user.auth)
        assert_equals(res.status_code, 302)
        assert_in(page_url, res.location)

    def test_wiki_id_url_get_returns_302_and_resolves(self):
        name = 'page by id'
        self.project.update_node_wiki(name, 'some content',
                                      Auth(self.project.creator))
        page = self.project.get_wiki_page(name)
        page_url = self.project.web_url_for('project_wiki_page',
                                            wname=page.page_name,
                                            _guid=True)
        url = self.project.web_url_for('project_wiki_id_page',
                                       wid=page._primary_key,
                                       _guid=True)
        res = self.app.get(url)
        assert_equal(res.status_code, 302)
        assert_in(page_url, res.location)
        res = res.follow()
        assert_equal(res.status_code, 200)
        assert_in(page_url, res.request.url)

    def test_wiki_id_url_get_returns_404(self):
        url = self.project.web_url_for('project_wiki_id_page',
                                       wid='12345',
                                       _guid=True)
        res = self.app.get(url, expect_errors=True)
        assert_equal(res.status_code, 404)

    def test_home_is_capitalized_in_web_view(self):
        url = self.project.web_url_for('project_wiki_home',
                                       wid='home',
                                       _guid=True)
        res = self.app.get(url,
                           auth=self.user.auth).follow(auth=self.user.auth)
        page_name_elem = res.html.find('span', {'id': 'pageName'})
        assert_in('Home', page_name_elem.text)
示例#49
0
class TestCreateBucket(S3AddonTestCase):
    def setUp(self):

        super(TestCreateBucket, self).setUp()

        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()

    def test_bad_names(self):
        assert_false(validate_bucket_name(''))
        assert_false(validate_bucket_name('no'))
        assert_false(validate_bucket_name('a' * 64))
        assert_false(validate_bucket_name(' leadingspace'))
        assert_false(validate_bucket_name('trailingspace '))
        assert_false(validate_bucket_name('bogus naMe'))
        assert_false(validate_bucket_name('.cantstartwithp'))
        assert_false(validate_bucket_name('or.endwith.'))
        assert_false(validate_bucket_name('..nodoubles'))
        assert_false(validate_bucket_name('no_unders_in'))
        assert_false(validate_bucket_name('-leadinghyphen'))
        assert_false(validate_bucket_name('trailinghyphen-'))
        assert_false(validate_bucket_name('Mixedcase'))
        assert_false(validate_bucket_name('empty..label'))
        assert_false(validate_bucket_name('label-.trailinghyphen'))
        assert_false(validate_bucket_name('label.-leadinghyphen'))
        assert_false(validate_bucket_name('8.8.8.8'))
        assert_false(validate_bucket_name('600.9000.0.28'))
        assert_false(validate_bucket_name('no_underscore'))
        assert_false(validate_bucket_name('_nounderscoreinfront'))
        assert_false(validate_bucket_name('no-underscore-in-back_'))
        assert_false(
            validate_bucket_name('no-underscore-in_the_middle_either'))

    def test_names(self):
        assert_true(validate_bucket_name('imagoodname'))
        assert_true(validate_bucket_name('still.passing'))
        assert_true(validate_bucket_name('can-have-dashes'))
        assert_true(validate_bucket_name('kinda.name.spaced'))
        assert_true(validate_bucket_name('a-o.valid'))
        assert_true(validate_bucket_name('11.12.m'))
        assert_true(validate_bucket_name('a--------a'))
        assert_true(validate_bucket_name('a' * 63))

    def test_bad_locations(self):
        assert_false(validate_bucket_location('Venus'))
        assert_false(validate_bucket_location('AlphaCentari'))
        assert_false(validate_bucket_location('CostaRica'))

    def test_locations(self):
        assert_true(validate_bucket_location(''))
        assert_true(validate_bucket_location('us-east-2'))
        assert_true(validate_bucket_location('eu-central-1'))
        assert_true(validate_bucket_location('us-west-1'))
        assert_true(validate_bucket_location('us-west-2'))
        assert_true(validate_bucket_location('ap-northeast-1'))
        assert_true(validate_bucket_location('ap-northeast-2'))
        assert_true(validate_bucket_location('ap-southeast-1'))
        assert_true(validate_bucket_location('ap-southeast-2'))
        assert_true(validate_bucket_location('ap-south-1'))
        assert_true(validate_bucket_location('sa-east-1'))
        assert_true(validate_bucket_location('eu-west-1'))

    @mock.patch('website.addons.s3.views.utils.create_bucket')
    @mock.patch('website.addons.s3.views.utils.get_bucket_names')
    def test_create_bucket_pass(self, mock_names, mock_make):
        mock_make.return_value = True
        mock_names.return_value = ['butintheend', 'it', 'doesntevenmatter']
        url = self.project.api_url_for('create_bucket')
        ret = self.app.post_json(url, {
            'bucket_name': 'doesntevenmatter',
            'bucket_location': '',
        },
                                 auth=self.user.auth)

        assert_equal(ret.status_int, http.OK)
        assert_equal(ret.json, {})

    @mock.patch('website.addons.s3.views.utils.create_bucket')
    def test_create_bucket_fail(self, mock_make):
        error = S3ResponseError(418, 'because Im a test')
        error.message = 'This should work'
        mock_make.side_effect = error

        url = "/api/v1/project/{0}/s3/newbucket/".format(self.project._id)
        ret = self.app.post_json(url, {'bucket_name': 'doesntevenmatter'},
                                 auth=self.user.auth,
                                 expect_errors=True)

        assert_equals(
            ret.body,
            '{"message": "This should work", "title": "Problem connecting to S3"}'
        )

    @mock.patch('website.addons.s3.views.utils.create_bucket')
    def test_bad_location_fails(self, mock_make):
        url = "/api/v1/project/{0}/s3/newbucket/".format(self.project._id)
        ret = self.app.post_json(
            url, {
                'bucket_name': 'doesntevenmatter',
                'bucket_location': 'not a real bucket location',
            },
            auth=self.user.auth,
            expect_errors=True)

        assert_equals(
            ret.body,
            '{"message": "That bucket location is not valid.", "title": "Invalid bucket location"}'
        )
示例#50
0
 def test_wiki_content_returns_200(self):
     node = ProjectFactory(is_public=True)
     url = node.api_url_for('wiki_page_content', wname='somerandomid')
     res = self.app.get(url)
     assert_equal(res.status_code, 200)
示例#51
0
class TestAddonLogs(OsfTestCase):

    def setUp(self):
        super(TestAddonLogs, self).setUp()
        self.flask_app = SetEnvironMiddleware(self.app.app, REMOTE_ADDR='127.0.0.1')
        self.test_app = webtest.TestApp(self.flask_app)
        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 = AddonGitHubOauthSettings(github_user_id='john')
        self.oauth_settings.save()
        self.user_addon.oauth_settings = self.oauth_settings
        self.user_addon.oauth_access_token = 'secret'
        self.user_addon.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.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,
        }

    def test_add_log(self):
        path = 'pizza'
        url = self.node.api_url_for('create_waterbutler_log')
        payload = self.build_payload(metadata={'path': path})
        nlogs = len(self.node.logs)
        self.test_app.put_json(url, payload, headers={'Content-Type': 'application/json'})
        self.node.reload()
        assert_equal(len(self.node.logs), nlogs + 1)

    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.test_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.test_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.test_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.test_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)
示例#52
0
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)
示例#53
0
class MendeleyViewsTestCase(OsfTestCase):
    def setUp(self):
        super(MendeleyViewsTestCase, self).setUp()
        self.account = MendeleyAccountFactory()
        self.user = AuthUserFactory(external_accounts=[self.account])
        self.account.display_name = self.user.fullname
        self.account.save()
        self.user_addon = MendeleyUserSettingsFactory(
            owner=self.user, external_account=self.account)
        self.project = ProjectFactory(creator=self.user)
        self.node_addon = MendeleyNodeSettingsFactory(owner=self.project)
        self.node_addon.set_auth(external_account=self.account, user=self.user)
        self.provider = MendeleyCitationsProvider()
        #self.user_addon.grant_oauth_access(self.node_addon, self.account, metadata={'lists': 'list'})
        self.node = MockNode()
        self.node.addon = self.node_addon
        self.id_patcher = mock.patch(
            'website.addons.mendeley.model.Mendeley.client_id')
        self.secret_patcher = mock.patch(
            'website.addons.mendeley.model.Mendeley.client_secret')
        self.id_patcher.__get__ = mock.Mock(return_value='1234567890asdf')
        self.secret_patcher.__get__ = mock.Mock(return_value='1234567890asdf')
        self.id_patcher.start()
        self.secret_patcher.start()

    def tearDown(self):
        self.id_patcher.stop()
        self.secret_patcher.stop()

    @mock.patch('website.addons.mendeley.model.Mendeley.client',
                new_callable=mock.PropertyMock)
    def test_check_mendeley_credentials(self, mock_client):
        mock_client.side_effect = HTTPError(403)
        assert_false(self.provider.check_credentials(self.node_addon))

        mock_client.side_effect = HTTPError(402)
        with assert_raises(HTTPError):
            self.provider.check_credentials(self.node_addon)

    @mock.patch(
        'website.addons.mendeley.views.MendeleyCitationsProvider.check_credentials'
    )
    def test_serialize_settings_authorizer(self, mock_credentials):
        #"""dict: a serialized version of user-specific addon settings"""
        mock_credentials.return_value = True
        res = self.app.get(
            self.project.api_url_for('mendeley_get_config'),
            auth=self.user.auth,
        )
        result = res.json['result']
        assert_true(result['nodeHasAuth'])
        assert_true(result['userHasAuth'])
        assert_true(result['userIsOwner'])
        assert_true(result['validCredentials'])
        assert_equal(result['folder'], {'name': ''})
        assert_equal(result['ownerName'], self.user.fullname)
        assert_true(result['urls']['auth'])
        assert_true(result['urls']['config'])
        assert_true(result['urls']['deauthorize'])
        assert_true(result['urls']['folders'])
        assert_true(result['urls']['importAuth'])
        assert_true(result['urls']['settings'])

    @mock.patch(
        'website.addons.mendeley.views.MendeleyCitationsProvider.check_credentials'
    )
    def test_serialize_settings_non_authorizer(self, mock_credentials):
        #"""dict: a serialized version of user-specific addon settings"""
        mock_credentials.return_value = True
        non_authorizing_user = AuthUserFactory()
        self.project.add_contributor(non_authorizing_user, save=True)
        res = self.app.get(
            self.project.api_url_for('mendeley_get_config'),
            auth=non_authorizing_user.auth,
        )
        result = res.json['result']
        assert_true(result['nodeHasAuth'])
        assert_false(result['userHasAuth'])
        assert_false(result['userIsOwner'])
        assert_true(result['validCredentials'])
        assert_equal(result['folder'], {'name': ''})
        assert_equal(result['ownerName'], self.user.fullname)
        assert_true(result['urls']['auth'])
        assert_true(result['urls']['config'])
        assert_true(result['urls']['deauthorize'])
        assert_true(result['urls']['folders'])
        assert_true(result['urls']['importAuth'])
        assert_true(result['urls']['settings'])

    @mock.patch(
        'website.addons.mendeley.provider.MendeleyCitationsProvider.check_credentials'
    )
    def test_set_auth(self, mock_credentials):

        mock_credentials.return_value = True
        res = self.app.put_json(
            self.project.api_url_for('mendeley_add_user_auth'),
            {
                'external_account_id': self.account._id,
            },
            auth=self.user.auth,
        )

        assert_equal(res.status_code, 200)

        assert_true(res.json['result']['userHasAuth'])

        assert_equal(self.node_addon.user_settings, self.user_addon)
        assert_equal(self.node_addon.external_account, self.account)

    def test_remove_user_auth(self):
        self.node_addon.set_auth(self.account, self.user)

        res = self.app.delete_json(
            self.project.api_url_for('mendeley_remove_user_auth'),
            {
                'external_account_id': self.account._id,
            },
            auth=self.user.auth,
        )

        assert_equal(res.status_code, 200)

        self.node_addon.reload()

        assert_is_none(self.node_addon.user_settings)
        assert_is_none(self.node_addon.external_account)

    @mock.patch('website.addons.mendeley.model.Mendeley._folder_metadata')
    def test_set_config_owner(self, mock_metadata):
        mock_metadata.return_value = MockFolder(name='Fake Folder')
        # Settings config updates node settings
        self.node_addon.associated_user_settings = []
        self.node_addon.save()
        res = self.app.put_json(
            self.project.api_url_for('mendeley_set_config'),
            {
                'external_account_id': self.account._id,
                'external_list_id': 'list',
            },
            auth=self.user.auth,
        )
        self.node_addon.reload()
        assert_equal(self.user_addon, self.node_addon.user_settings)
        serializer = MendeleySerializer(node_settings=self.node_addon,
                                        user_settings=self.user_addon)
        expected = {'result': serializer.serialized_node_settings}
        assert_equal(res.json, expected)

    @mock.patch('website.addons.mendeley.model.Mendeley._folder_metadata')
    def test_set_config_not_owner(self, mock_metadata):
        mock_metadata.return_value = MockFolder(name='Fake Folder')
        user = AuthUserFactory()
        user.add_addon('mendeley')
        self.project.add_contributor(user)
        self.project.save()
        res = self.app.put_json(
            self.project.api_url_for('mendeley_set_config'),
            {
                'external_account_id': self.account._id,
                'external_list_id': 'list',
            },
            auth=user.auth,
        )
        self.node_addon.reload()
        assert_equal(self.user_addon, self.node_addon.user_settings)
        serializer = MendeleySerializer(node_settings=self.node_addon,
                                        user_settings=None)
        expected = {'result': serializer.serialized_node_settings}
        assert_equal(res.json, expected)

    def test_mendeley_widget_view_complete(self):
        # JSON: everything a widget needs
        assert_false(self.node_addon.complete)
        assert_equal(self.node_addon.mendeley_list_id, None)
        self.node_addon.set_target_folder('ROOT-ID',
                                          'ROOT',
                                          auth=Auth(user=self.user))
        url = self.project.api_url_for('mendeley_widget')
        res = self.app.get(url, auth=self.user.auth).json

        assert_true(res['complete'])
        assert_equal(res['list_id'], 'ROOT-ID')

    def test_widget_view_incomplete(self):
        # JSON: tell the widget when it hasn't been configured
        assert_false(self.node_addon.complete)
        assert_equal(self.node_addon.mendeley_list_id, None)
        url = self.project.api_url_for('mendeley_widget')
        res = self.app.get(url, auth=self.user.auth).json

        assert_false(res['complete'])
        assert_is_none(res['list_id'])

    @httpretty.activate
    def test_mendeley_citation_list_root(self):

        httpretty.register_uri(httpretty.GET,
                               urlparse.urljoin(API_URL, 'folders'),
                               body=mock_responses['folders'],
                               content_type='application/json')

        res = self.app.get(self.project.api_url_for('mendeley_citation_list'),
                           auth=self.user.auth)
        root = res.json['contents'][0]
        assert_equal(root['kind'], 'folder')
        assert_equal(root['id'], 'ROOT')
        assert_equal(root['parent_list_id'], '__')

    @httpretty.activate
    def test_mendeley_citation_list_non_root(self):

        httpretty.register_uri(httpretty.GET,
                               urlparse.urljoin(API_URL, 'folders'),
                               body=mock_responses['folders'],
                               content_type='application/json')

        httpretty.register_uri(httpretty.GET,
                               urlparse.urljoin(API_URL, 'documents'),
                               body=mock_responses['documents'],
                               content_type='application/json')

        res = self.app.get(self.project.api_url_for('mendeley_citation_list',
                                                    mendeley_list_id='ROOT'),
                           auth=self.user.auth)

        children = res.json['contents']
        assert_equal(len(children), 7)
        assert_equal(children[0]['kind'], 'folder')
        assert_equal(children[1]['kind'], 'file')
        assert_true(children[1].get('csl') is not None)

    @httpretty.activate
    def test_mendeley_citation_list_non_linked_or_child_non_authorizer(self):

        non_authorizing_user = AuthUserFactory()
        self.project.add_contributor(non_authorizing_user, save=True)

        self.node_addon.mendeley_list_id = 'e843da05-8818-47c2-8c37-41eebfc4fe3f'
        self.node_addon.save()

        httpretty.register_uri(httpretty.GET,
                               urlparse.urljoin(API_URL, 'folders'),
                               body=mock_responses['folders'],
                               content_type='application/json')

        httpretty.register_uri(httpretty.GET,
                               urlparse.urljoin(API_URL, 'documents'),
                               body=mock_responses['documents'],
                               content_type='application/json')

        res = self.app.get(self.project.api_url_for('mendeley_citation_list',
                                                    mendeley_list_id='ROOT'),
                           auth=non_authorizing_user.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 403)
示例#54
0
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 RegistrationEmbargoViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationEmbargoViewsTestCase, self).setUp()
        ensure_schemas()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        self.registration = RegistrationFactory(project=self.project, creator=self.user)

        current_month = datetime.datetime.now().strftime("%B")
        current_year = datetime.datetime.now().strftime("%Y")

        self.valid_make_public_payload = json.dumps(
            {
                u"embargoEndDate": u"Fri, 01, {month} {year} 00:00:00 GMT".format(
                    month=current_month, year=current_year
                ),
                u"registrationChoice": "immediate",
                u"summary": unicode(fake.sentence()),
            }
        )
        valid_date = datetime.datetime.now() + datetime.timedelta(days=180)
        self.valid_embargo_payload = json.dumps(
            {
                u"embargoEndDate": unicode(valid_date.strftime("%a, %d, %B %Y %H:%M:%S")) + u" GMT",
                u"registrationChoice": "embargo",
                u"summary": unicode(fake.sentence()),
            }
        )
        self.invalid_embargo_date_payload = json.dumps(
            {
                u"embargoEndDate": u"Thu, 01 {month} {year} 05:00:00 GMT".format(
                    month=current_month, year=str(int(current_year) - 1)
                ),
                u"registrationChoice": "embargo",
                u"summary": unicode(fake.sentence()),
            }
        )

    @mock.patch("framework.tasks.handlers.enqueue_task")
    def test_POST_register_make_public_immediately_creates_registration_approval(self, mock_enqueue):
        res = self.app.post(
            self.project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"),
            self.valid_make_public_payload,
            content_type="application/json",
            auth=self.user.auth,
        )
        assert_equal(res.status_code, 201)

        registration = Node.find().sort("-registered_date")[0]

        assert_true(registration.is_registration)
        assert_not_equal(registration.registration_approval, None)

    # Regression test for https://openscience.atlassian.net/browse/OSF-5039
    @mock.patch("framework.tasks.handlers.enqueue_task")
    def test_POST_register_make_public_immediately_creates_private_pending_registration_for_public_project(
        self, mock_enqueue
    ):
        public_project = ProjectFactory(is_public=True, creator=self.user)
        component = NodeFactory(creator=self.user, parent=public_project, title="Component", is_public=True)
        subproject = ProjectFactory(creator=self.user, parent=public_project, title="Subproject", is_public=True)
        subproject_component = NodeFactory(creator=self.user, parent=subproject, title="Subcomponent", is_public=True)
        res = self.app.post(
            public_project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"),
            self.valid_make_public_payload,
            content_type="application/json",
            auth=self.user.auth,
        )
        public_project.reload()
        assert_equal(res.status_code, 201)

        # Last node directly registered from self.project
        registration = Node.load(public_project.node__registrations[-1])

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch("framework.tasks.handlers.enqueue_task")
    def test_POST_register_make_public_does_not_make_children_public(self, mock_enqueue):
        component = NodeFactory(creator=self.user, parent=self.project, title="Component")
        subproject = ProjectFactory(creator=self.user, parent=self.project, title="Subproject")
        subproject_component = NodeFactory(creator=self.user, parent=subproject, title="Subcomponent")

        res = self.app.post(
            self.project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"),
            self.valid_make_public_payload,
            content_type="application/json",
            auth=self.user.auth,
        )
        self.project.reload()
        # Last node directly registered from self.project
        registration = Node.load(self.project.node__registrations[-1])
        assert_false(registration.is_public)
        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch("framework.tasks.handlers.enqueue_task")
    def test_POST_register_embargo_is_not_public(self, mock_enqueue):
        res = self.app.post(
            self.project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"),
            self.valid_embargo_payload,
            content_type="application/json",
            auth=self.user.auth,
        )

        assert_equal(res.status_code, 201)

        registration = Node.find().sort("-registered_date")[0]

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        assert_true(registration.is_pending_embargo_for_existing_registration)
        assert_is_not_none(registration.embargo)

    # Regression test for https://openscience.atlassian.net/browse/OSF-5071
    @mock.patch("framework.tasks.handlers.enqueue_task")
    def test_POST_register_embargo_does_not_make_project_or_children_public(self, mock_enqueue):
        public_project = ProjectFactory(creator=self.user, is_public=True)
        component = NodeFactory(creator=self.user, parent=public_project, title="Component", is_public=True)
        subproject = ProjectFactory(creator=self.user, parent=public_project, title="Subproject", is_public=True)
        subproject_component = NodeFactory(creator=self.user, parent=subproject, title="Subcomponent", is_public=True)
        res = self.app.post(
            public_project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"),
            self.valid_embargo_payload,
            content_type="application/json",
            auth=self.user.auth,
        )
        public_project.reload()
        assert_equal(res.status_code, 201)

        # Last node directly registered from self.project
        registration = Node.load(public_project.node__registrations[-1])

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        assert_true(registration.is_pending_embargo_for_existing_registration)
        assert_is_not_none(registration.embargo)

        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch("framework.tasks.handlers.enqueue_task")
    def test_POST_invalid_embargo_end_date_returns_HTTPBad_Request(self, mock_enqueue):
        res = self.app.post(
            self.project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"),
            self.invalid_embargo_date_payload,
            content_type="application/json",
            auth=self.user.auth,
            expect_errors=True,
        )

        assert_equal(res.status_code, 400)

    @mock.patch("framework.tasks.handlers.enqueue_task")
    def test_valid_POST_embargo_adds_to_parent_projects_log(self, mock_enquque):
        initial_project_logs = len(self.project.logs)
        res = self.app.post(
            self.project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"),
            self.valid_embargo_payload,
            content_type="application/json",
            auth=self.user.auth,
        )
        self.project.reload()
        # Logs: Created, registered, embargo initiated
        assert_equal(len(self.project.logs), initial_project_logs + 1)

    def test_non_contributor_GET_approval_returns_HTTPError(self):
        non_contributor = AuthUserFactory()
        self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[self.user._id]["approval_token"]
        approval_url = self.registration.web_url_for("view_project", token=approval_token)

        res = self.app.get(approval_url, auth=non_contributor.auth, expect_errors=True)
        assert_equal(http.FORBIDDEN, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

    def test_non_contributor_GET_disapproval_returns_HTTPError(self):
        non_contributor = AuthUserFactory()
        self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[self.user._id]["rejection_token"]
        approval_url = self.registration.web_url_for("view_project", token=rejection_token)

        res = self.app.get(approval_url, auth=non_contributor.auth, expect_errors=True)
        assert_equal(http.FORBIDDEN, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)
示例#56
0
 def test_wiki_content_returns_200(self):
     node = ProjectFactory(is_public=True)
     url = node.api_url_for('wiki_page_content', wname='somerandomid')
     res = self.app.get(url)
     assert_equal(res.status_code, 200)
示例#57
0
class TestRmapNodeViews(OsfTestCase):
    def setUp(self):
        super(TestRmapNodeViews, self).setUp()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user, is_public=True)
        self.url = self.project.api_url_for('node_rmap_post')

        self._old_rmap_url = settings.RMAP_BASE_URL
        self._old_rmap_pass = settings.RMAP_PASS

        settings.RMAP_BASE_URL = 'rmaptest.test/'
        settings.RMAP_PASS = '******'

        self._set_up_mock_response_for_node(self.project)

    def _set_up_mock_response_for_node(self, node):
        rmap_url = _rmap_url_for_node(node)
        httpretty.register_uri(httpretty.POST,
                               rmap_url,
                               body='abc123',
                               status=200)

    def tearDown(self):
        super(TestRmapNodeViews, self).tearDown()
        settings.RMAP_BASE_URL = self._old_rmap_url
        settings.RMAP_PASS = self._old_rmap_pass

    def test_rmap_get_valid_no_disco_id(self):
        res = self.app.get(self.url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['disco_id'], None)

    def test_rmap_get_valid_with_disco_id(self):
        disco_id = 'pan1cath3d1sc0'
        self.project.set_identifier_value('disco', disco_id)
        res = self.app.get(self.url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['disco_id'], disco_id)

    def test_rmap_post_valid(self):
        res = self.app.post_json(self.url, {}, auth=self.user.auth)
        assert_equal(res.status_code, 201)
        self.project.reload()

        rmap_id = self.project.get_identifier('disco')
        assert_true(bool(rmap_id))
        assert_equal(rmap_id.value, 'abc123')

    def test_rmap_post_non_contributor_should_error(self):
        noncontrib = AuthUserFactory()
        res = self.app.post_json(self.url, {},
                                 auth=noncontrib.auth,
                                 expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_rmap_post_non_admin_contributor_should_error(self):
        non_admin = AuthUserFactory()
        self.project.add_contributor(non_admin,
                                     permissions=['read', 'write'],
                                     auth=Auth(self.user))
        self.project.save()
        res = self.app.post_json(self.url, {},
                                 auth=non_admin.auth,
                                 expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_rmap_post_non_public_project_should_error(self):
        private_project = ProjectFactory(creator=self.user, is_public=False)
        url = private_project.api_url_for('node_rmap_post')
        res = self.app.post_json(url, {},
                                 auth=self.user.auth,
                                 expect_errors=True)
        assert_equal(res.status_code, 400)