Пример #1
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)
Пример #2
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)
    def test_node_count_deleted_addon(self):
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['nodes']['deleted'], 0)

        node = ProjectFactory(creator=self.user)
        node.add_addon('github', Auth(self.user))
        node_addon = node.get_addon('github')
        node_addon.delete()

        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['nodes']['deleted'], 1)
Пример #4
0
class TestRegistrationsWithGithub(OsfTestCase):
    def setUp(self):

        super(TestRegistrationsWithGithub, self).setUp()
        self.project = ProjectFactory()
        self.consolidated_auth = Auth(user=self.project.creator)

        self.project.add_addon('github', auth=self.consolidated_auth)
        self.project.creator.add_addon('github')
        self.node_settings = self.project.get_addon('github')
        self.user_settings = self.project.creator.get_addon('github')
        self.node_settings.user_settings = self.user_settings
        self.node_settings.user = '******'
        self.node_settings.repo = 'Sheer-Heart-Attack'
        self.node_settings.save()
Пример #5
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.add(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)
Пример #6
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.add(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)
Пример #7
0
class TestCRUD(OsfTestCase):

    def setUp(self):
        super(TestCRUD, self).setUp()
        self.gitlab = create_mock_gitlab(user='******', private=False)
        self.user = AuthUserFactory()
        self.consolidated_auth = Auth(user=self.user)
        self.project = ProjectFactory(creator=self.user)
        self.project.add_addon('gitlab', auth=self.consolidated_auth)
        self.project.creator.add_addon('gitlab')
        self.node_settings = self.project.get_addon('gitlab')
        self.node_settings.user_settings = self.project.creator.get_addon('gitlab')
        # Set the node addon settings to correspond to the values of the mock repo
        self.node_settings.user = self.gitlab.repo.return_value.owner.login
        self.node_settings.repo = self.gitlab.repo.return_value.name
        self.node_settings.save()
Пример #8
0
class TestCRUD(OsfTestCase):
    def setUp(self):
        super(TestCRUD, self).setUp()
        self.gitlab = create_mock_gitlab(user='******', private=False)
        self.user = AuthUserFactory()
        self.consolidated_auth = Auth(user=self.user)
        self.project = ProjectFactory(creator=self.user)
        self.project.add_addon('gitlab', auth=self.consolidated_auth)
        self.project.creator.add_addon('gitlab')
        self.node_settings = self.project.get_addon('gitlab')
        self.node_settings.user_settings = self.project.creator.get_addon(
            'gitlab')
        # Set the node addon settings to correspond to the values of the mock repo
        self.node_settings.user = self.gitlab.repo.return_value.owner.login
        self.node_settings.repo = self.gitlab.repo.return_value.name
        self.node_settings.save()
Пример #9
0
class TestRegistrationsWithGithub(OsfTestCase):

    def setUp(self):

        super(TestRegistrationsWithGithub, self).setUp()
        self.project = ProjectFactory()
        self.consolidated_auth = Auth(user=self.project.creator)

        self.project.add_addon('github', auth=self.consolidated_auth)
        self.project.creator.add_addon('github')
        self.node_settings = self.project.get_addon('github')
        self.user_settings = self.project.creator.get_addon('github')
        self.node_settings.user_settings = self.user_settings
        self.node_settings.user = '******'
        self.node_settings.repo = 'Sheer-Heart-Attack'
        self.node_settings.save()
Пример #10
0
class TestGithubViews(OsfTestCase):

    def setUp(self):
        super(TestGithubViews, self).setUp()
        self.user = AuthUserFactory()
        self.consolidated_auth = Auth(user=self.user)

        self.project = ProjectFactory(creator=self.user)
        self.non_authenticator = UserFactory()
        self.project.add_contributor(
            contributor=self.non_authenticator,
            auth=self.consolidated_auth,
        )
        self.project.creator.add_addon('github')
        self.project.creator.external_accounts.add(GitHubAccountFactory())
        self.project.creator.save()
        self.project.save()
        self.project.add_addon('github', auth=self.consolidated_auth)

        self.github = create_mock_github(user='******', private=False)

        self.node_settings = self.project.get_addon('github')
        self.node_settings.user_settings = self.project.creator.get_addon('github')
        # Set the node addon settings to correspond to the values of the mock repo
        self.node_settings.user = self.github.repo.return_value.owner.login
        self.node_settings.repo = self.github.repo.return_value.name
        self.node_settings.save()

    def _get_sha_for_branch(self, branch=None, mock_branches=None):
        github_mock = self.github
        if mock_branches is None:
            mock_branches = github_mock.branches
        if branch is None:  # Get default branch name
            branch = self.github.repo.return_value.default_branch
        for each in mock_branches.return_value:
            if each.name == branch:
                branch_sha = each.commit.sha
        return branch_sha

    # Tests for _get_refs
    @mock.patch('addons.github.api.GitHubClient.branches')
    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_get_refs_defaults(self, mock_repo, mock_branches):
        github_mock = self.github
        mock_repo.return_value = github_mock.repo.return_value
        mock_branches.return_value = github_mock.branches.return_value
        branch, sha, branches = utils.get_refs(self.node_settings)
Пример #11
0
    def test_node_count_deleted_addon(self):
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['nodes']['deleted'], 0)

        node = ProjectFactory(creator=self.user)
        node.add_addon('github', Auth(self.user))
        node_addon = node.get_addon('github')
        node_addon.delete()

        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['nodes']['deleted'], 1)
    def test_many_nodes_with_one_addon(self):
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['nodes']['total'], 1)

        node = ProjectFactory(creator=self.user)
        node.add_addon('github', Auth(self.user))
        node_addon = node.get_addon('github')
        node_addon.user = self.user.fullname
        node_addon.repo = '8 (circle)'
        node_addon.user_settings = self.user_addon
        node_addon.external_account = self.external_account
        node_addon.save()
        node.save()

        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['nodes']['total'], 2)
Пример #13
0
class AddonNodeLoggerTestSuiteMixinBase(object):

    __metaclass__ = abc.ABCMeta

    @abc.abstractproperty
    def addon_short_name(self):
        pass

    @abc.abstractproperty
    def NodeLogger(self):
        pass

    def setUp(self):
        super(AddonNodeLoggerTestSuiteMixinBase, self).setUp()
        self.auth = Auth(AuthUserFactory())
        self.node = ProjectFactory(creator=self.auth.user)
        self.path = None
        self.node.add_addon(self.addon_short_name, auth=self.auth)
        self.logger = self.NodeLogger(node=self.node, auth=self.auth)
Пример #14
0
    def test_many_nodes_with_one_addon(self):
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['nodes']['total'], 1)

        node = ProjectFactory(creator=self.user)
        node.add_addon('github', Auth(self.user))
        node_addon = node.get_addon('github')
        node_addon.user = self.user.fullname
        node_addon.repo = '8 (circle)'
        node_addon.user_settings = self.user_addon
        node_addon.external_account = self.external_account
        node_addon.save()
        node.save()

        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['nodes']['total'], 2)
Пример #15
0
class TestMustHaveAddonDecorator(AuthAppTestCase):

    def setUp(self):
        super(TestMustHaveAddonDecorator, self).setUp()
        self.project = ProjectFactory()

    @mock.patch('website.project.decorators._kwargs_to_nodes')
    def test_must_have_addon_node_true(self, mock_kwargs_to_nodes):
        mock_kwargs_to_nodes.return_value = (None, self.project)
        self.project.add_addon('github', auth=None)
        decorated = must_have_addon('github', 'node')(needs_addon_view)
        res = decorated()
        assert_equal(res, 'openaddon')

    @mock.patch('website.project.decorators._kwargs_to_nodes')
    def test_must_have_addon_node_false(self, mock_kwargs_to_nodes):
        mock_kwargs_to_nodes.return_value = (None, self.project)
        self.project.delete_addon('github', auth=None)
        decorated = must_have_addon('github', 'node')(needs_addon_view)
        with assert_raises(HTTPError):
            decorated()

    @mock.patch('framework.auth.decorators.Auth.from_kwargs')
    def test_must_have_addon_user_true(self, mock_current_user):
        mock_current_user.return_value = Auth(self.project.creator)
        self.project.creator.add_addon('github')
        decorated = must_have_addon('github', 'user')(needs_addon_view)
        res = decorated()
        assert_equal(res, 'openaddon')

    @mock.patch('framework.auth.decorators.Auth.from_kwargs')
    def test_must_have_addon_user_false(self, mock_current_user):
        mock_current_user.return_value = Auth(self.project.creator)
        self.project.creator.delete_addon('github')
        decorated = must_have_addon('github', 'user')(needs_addon_view)
        with assert_raises(HTTPError):
            decorated()
Пример #16
0
class TestMustHaveAddonDecorator(AuthAppTestCase):

    def setUp(self):
        super(TestMustHaveAddonDecorator, self).setUp()
        self.project = ProjectFactory()

    @mock.patch('website.project.decorators._kwargs_to_nodes')
    def test_must_have_addon_node_true(self, mock_kwargs_to_nodes):
        mock_kwargs_to_nodes.return_value = (None, self.project)
        self.project.add_addon('github', auth=None)
        decorated = must_have_addon('github', 'node')(needs_addon_view)
        res = decorated()
        assert_equal(res, 'openaddon')

    @mock.patch('website.project.decorators._kwargs_to_nodes')
    def test_must_have_addon_node_false(self, mock_kwargs_to_nodes):
        mock_kwargs_to_nodes.return_value = (None, self.project)
        self.project.delete_addon('github', auth=None)
        decorated = must_have_addon('github', 'node')(needs_addon_view)
        with assert_raises(HTTPError):
            decorated()

    @mock.patch('framework.auth.decorators.Auth.from_kwargs')
    def test_must_have_addon_user_true(self, mock_current_user):
        mock_current_user.return_value = Auth(self.project.creator)
        self.project.creator.add_addon('github')
        decorated = must_have_addon('github', 'user')(needs_addon_view)
        res = decorated()
        assert_equal(res, 'openaddon')

    @mock.patch('framework.auth.decorators.Auth.from_kwargs')
    def test_must_have_addon_user_false(self, mock_current_user):
        mock_current_user.return_value = Auth(self.project.creator)
        self.project.creator.delete_addon('github')
        decorated = must_have_addon('github', 'user')(needs_addon_view)
        with assert_raises(HTTPError):
            decorated()
Пример #17
0
class TestMustBeAddonAuthorizerDecorator(AuthAppTestCase):

    def setUp(self):
        super(TestMustBeAddonAuthorizerDecorator, self).setUp()
        self.project = ProjectFactory()
        self.decorated = must_be_addon_authorizer('github')(needs_addon_view)

    @mock.patch('website.project.decorators._kwargs_to_nodes')
    @mock.patch('framework.auth.decorators.Auth.from_kwargs')
    def test_must_be_authorizer_true(self, mock_get_current_user, mock_kwargs_to_nodes):

        # Mock
        mock_get_current_user.return_value = Auth(self.project.creator)
        mock_kwargs_to_nodes.return_value = (None, self.project)

        # Setup
        self.project.add_addon('github', auth=None)
        node_settings = self.project.get_addon('github')
        self.project.creator.add_addon('github')
        user_settings = self.project.creator.get_addon('github')
        node_settings.user_settings = user_settings
        node_settings.save()

        # Test
        res = self.decorated()
        assert_equal(res, 'openaddon')

    def test_must_be_authorizer_false(self):

        # Setup
        self.project.add_addon('github', auth=None)
        node_settings = self.project.get_addon('github')
        user2 = UserFactory()
        user2.add_addon('github')
        user_settings = user2.get_addon('github')
        node_settings.user_settings = user_settings
        node_settings.save()

        # Test
        with assert_raises(HTTPError):
            self.decorated()

    def test_must_be_authorizer_no_user_settings(self):
        self.project.add_addon('github', auth=None)
        with assert_raises(HTTPError):
            self.decorated()

    def test_must_be_authorizer_no_node_settings(self):
        with assert_raises(HTTPError):
            self.decorated()
Пример #18
0
class TestMustBeAddonAuthorizerDecorator(AuthAppTestCase):
    def setUp(self):
        super(TestMustBeAddonAuthorizerDecorator, self).setUp()
        self.project = ProjectFactory()
        self.decorated = must_be_addon_authorizer('github')(needs_addon_view)

    @mock.patch('website.project.decorators._kwargs_to_nodes')
    @mock.patch('framework.auth.decorators.Auth.from_kwargs')
    def test_must_be_authorizer_true(self, mock_get_current_user,
                                     mock_kwargs_to_nodes):

        # Mock
        mock_get_current_user.return_value = Auth(self.project.creator)
        mock_kwargs_to_nodes.return_value = (None, self.project)

        # Setup
        self.project.add_addon('github', auth=None)
        node_settings = self.project.get_addon('github')
        self.project.creator.add_addon('github')
        user_settings = self.project.creator.get_addon('github')
        node_settings.user_settings = user_settings
        node_settings.save()

        # Test
        res = self.decorated()
        assert_equal(res, 'openaddon')

    def test_must_be_authorizer_false(self):

        # Setup
        self.project.add_addon('github', auth=None)
        node_settings = self.project.get_addon('github')
        user2 = UserFactory()
        user2.add_addon('github')
        user_settings = user2.get_addon('github')
        node_settings.user_settings = user_settings
        node_settings.save()

        # Test
        with assert_raises(HTTPError):
            self.decorated()

    def test_must_be_authorizer_no_user_settings(self):
        self.project.add_addon('github', auth=None)
        with assert_raises(HTTPError):
            self.decorated()

    def test_must_be_authorizer_no_node_settings(self):
        with assert_raises(HTTPError):
            self.decorated()
Пример #19
0
class TestGithubViews(OsfTestCase):
    def setUp(self):
        super(TestGithubViews, self).setUp()
        self.user = AuthUserFactory()
        self.consolidated_auth = Auth(user=self.user)

        self.project = ProjectFactory(creator=self.user)
        self.non_authenticator = UserFactory()
        self.project.add_contributor(
            contributor=self.non_authenticator,
            auth=self.consolidated_auth,
        )
        self.project.creator.add_addon('github')
        self.project.creator.external_accounts.add(GitHubAccountFactory())
        self.project.creator.save()
        self.project.save()
        self.project.add_addon('github', auth=self.consolidated_auth)

        self.github = create_mock_github(user='******', private=False)

        self.node_settings = self.project.get_addon('github')
        self.node_settings.user_settings = self.project.creator.get_addon(
            'github')
        # Set the node addon settings to correspond to the values of the mock repo
        self.node_settings.user = self.github.repo.return_value.owner.login
        self.node_settings.repo = self.github.repo.return_value.name
        self.node_settings.save()

    def _get_sha_for_branch(self, branch=None, mock_branches=None):
        github_mock = self.github
        if mock_branches is None:
            mock_branches = github_mock.branches
        if branch is None:  # Get default branch name
            branch = self.github.repo.return_value.default_branch
        for each in mock_branches.return_value:
            if each.name == branch:
                branch_sha = each.commit.sha
        return branch_sha

    # Tests for _get_refs
    @mock.patch('addons.github.api.GitHubClient.branches')
    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_get_refs_defaults(self, mock_repo, mock_branches):
        github_mock = self.github
        mock_repo.return_value = github_mock.repo.return_value
        mock_branches.return_value = github_mock.branches.return_value
        branch, sha, branches = utils.get_refs(self.node_settings)
        assert_equal(branch, github_mock.repo.return_value.default_branch)
        assert_equal(sha, self._get_sha_for_branch(
            branch=None))  # Get refs for default branch
        assert_equal(branches, github_mock.branches.return_value)

    @mock.patch('addons.github.api.GitHubClient.branches')
    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_get_refs_branch(self, mock_repo, mock_branches):
        github_mock = self.github
        mock_repo.return_value = github_mock.repo.return_value
        mock_branches.return_value = github_mock.branches.return_value
        branch, sha, branches = utils.get_refs(self.node_settings, 'master')
        assert_equal(branch, 'master')
        branch_sha = self._get_sha_for_branch('master')
        assert_equal(sha, branch_sha)
        assert_equal(branches, github_mock.branches.return_value)

    def test_before_fork(self):
        url = self.project.api_url + 'fork/before/'
        res = self.app.get(url, auth=self.user.auth).maybe_follow()
        assert_equal(len(res.json['prompts']), 1)

    def test_get_refs_sha_no_branch(self):
        with assert_raises(HTTPError):
            utils.get_refs(self.node_settings, sha='12345')

    def test_get_refs_registered_missing_branch(self):
        github_mock = self.github
        self.node_settings.registration_data = {
            'branches':
            [branch.to_json() for branch in github_mock.branches.return_value]
        }
        with mock.patch('osf.models.node.AbstractNode.is_registration',
                        new_callable=mock.PropertyMock) as mock_is_reg:
            mock_is_reg.return_value = True
            with assert_raises(HTTPError):
                utils.get_refs(self.node_settings, branch='nothere')

    # Tests for _check_permissions
    # make a user with no authorization; make sure check_permissions returns false
    def test_permissions_no_auth(self):
        github_mock = self.github
        # project is set to private right now
        connection = github_mock
        non_authenticated_user = UserFactory()
        non_authenticated_auth = Auth(user=non_authenticated_user)
        branch = 'master'
        assert_false(
            check_permissions(self.node_settings, non_authenticated_auth,
                              connection, branch))

    # make a repository that doesn't allow push access for this user;
    # make sure check_permissions returns false
    @mock.patch('addons.github.models.UserSettings.has_auth')
    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_permissions_no_access(self, mock_repo, mock_has_auth):
        github_mock = self.github
        mock_has_auth.return_value = True
        connection = github_mock
        branch = 'master'
        mock_repository = mock.NonCallableMock()
        mock_repository.user = '******'
        mock_repository.repo = 'mock-repo'
        mock_repository.to_json.return_value = {
            'user': '******',
            'repo': 'mock-repo',
            'permissions': {
                'push': False,  # this is key
            },
        }
        mock_repo.return_value = mock_repository
        assert_false(
            check_permissions(self.node_settings,
                              self.consolidated_auth,
                              connection,
                              branch,
                              repo=mock_repository))

    # make a branch with a different commit than the commit being passed into check_permissions
    @mock.patch('addons.github.models.UserSettings.has_auth')
    def test_permissions_not_head(self, mock_has_auth):
        github_mock = self.github
        mock_has_auth.return_value = True
        connection = github_mock
        mock_branch = mock.NonCallableMock()
        mock_branch.commit.sha = '67890'
        sha = '12345'
        assert_false(
            check_permissions(self.node_settings,
                              self.consolidated_auth,
                              connection,
                              mock_branch,
                              sha=sha))

    # make sure permissions are not granted for editing a registration
    @mock.patch('addons.github.models.UserSettings.has_auth')
    def test_permissions(self, mock_has_auth):
        github_mock = self.github
        mock_has_auth.return_value = True
        connection = github_mock
        with mock.patch('osf.models.node.AbstractNode.is_registration',
                        new_callable=mock.PropertyMock) as mock_is_reg:
            mock_is_reg.return_value = True
            assert_false(
                check_permissions(self.node_settings, self.consolidated_auth,
                                  connection, 'master'))

    def check_hook_urls(self, urls, node, path, sha):
        url = node.web_url_for('addon_view_or_download_file',
                               path=path,
                               provider='github')
        expected_urls = {
            'view': '{0}?ref={1}'.format(url, sha),
            'download': '{0}?action=download&ref={1}'.format(url, sha)
        }

        assert_equal(urls['view'], expected_urls['view'])
        assert_equal(urls['download'], expected_urls['download'])

    @mock.patch('addons.github.views.verify_hook_signature')
    def test_hook_callback_add_file_not_thro_osf(self, mock_verify):
        url = '/api/v1/project/{0}/github/hook/'.format(self.project._id)
        timestamp = str(timezone.now())
        self.app.post_json(
            url,
            {
                "test":
                True,
                "commits": [{
                    "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                    "distinct": True,
                    "message": "foo",
                    "timestamp": timestamp,
                    "url":
                    "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                    "author": {
                        "name": "Illidan",
                        "email": "*****@*****.**"
                    },
                    "committer": {
                        "name": "Testor",
                        "email": "*****@*****.**",
                        "username": "******"
                    },
                    "added": ["PRJWN3TV"],
                    "removed": [],
                    "modified": [],
                }]
            },
            content_type="application/json",
        ).maybe_follow()
        self.project.reload()
        assert_equal(self.project.logs.latest().action, "github_file_added")
        urls = self.project.logs.latest().params['urls']
        self.check_hook_urls(
            urls,
            self.project,
            path='PRJWN3TV',
            sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
        )

    @mock.patch('addons.github.views.verify_hook_signature')
    def test_hook_callback_modify_file_not_thro_osf(self, mock_verify):
        url = "/api/v1/project/{0}/github/hook/".format(self.project._id)
        timestamp = str(timezone.now())
        self.app.post_json(url, {
            "test":
            True,
            "commits": [{
                "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                "distinct": True,
                "message": " foo",
                "timestamp": timestamp,
                "url":
                "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                "author": {
                    "name": "Illidan",
                    "email": "*****@*****.**"
                },
                "committer": {
                    "name": "Testor",
                    "email": "*****@*****.**",
                    "username": "******"
                },
                "added": [],
                "removed": [],
                "modified": ["PRJWN3TV"]
            }]
        },
                           content_type="application/json").maybe_follow()
        self.project.reload()
        assert_equal(self.project.logs.latest().action, "github_file_updated")
        urls = self.project.logs.latest().params['urls']
        self.check_hook_urls(
            urls,
            self.project,
            path='PRJWN3TV',
            sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
        )

    @mock.patch('addons.github.views.verify_hook_signature')
    def test_hook_callback_remove_file_not_thro_osf(self, mock_verify):
        url = "/api/v1/project/{0}/github/hook/".format(self.project._id)
        timestamp = str(timezone.now())
        self.app.post_json(url, {
            "test":
            True,
            "commits": [{
                "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                "distinct": True,
                "message": "foo",
                "timestamp": timestamp,
                "url":
                "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                "author": {
                    "name": "Illidan",
                    "email": "*****@*****.**"
                },
                "committer": {
                    "name": "Testor",
                    "email": "*****@*****.**",
                    "username": "******"
                },
                "added": [],
                "removed": ["PRJWN3TV"],
                "modified": []
            }]
        },
                           content_type="application/json").maybe_follow()
        self.project.reload()
        assert_equal(self.project.logs.latest().action, "github_file_removed")
        urls = self.project.logs.latest().params['urls']
        assert_equal(urls, {})

    @mock.patch('addons.github.views.verify_hook_signature')
    def test_hook_callback_add_file_thro_osf(self, mock_verify):
        url = "/api/v1/project/{0}/github/hook/".format(self.project._id)
        self.app.post_json(url, {
            "test":
            True,
            "commits": [{
                "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                "distinct": True,
                "message": "Added via the Open Science Framework",
                "timestamp": "2014-01-08T14:15:51-08:00",
                "url":
                "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                "author": {
                    "name": "Illidan",
                    "email": "*****@*****.**"
                },
                "committer": {
                    "name": "Testor",
                    "email": "*****@*****.**",
                    "username": "******"
                },
                "added": ["PRJWN3TV"],
                "removed": [],
                "modified": []
            }]
        },
                           content_type="application/json").maybe_follow()
        self.project.reload()
        assert_not_equal(self.project.logs.latest().action,
                         "github_file_added")

    @mock.patch('addons.github.views.verify_hook_signature')
    def test_hook_callback_modify_file_thro_osf(self, mock_verify):
        url = "/api/v1/project/{0}/github/hook/".format(self.project._id)
        self.app.post_json(url, {
            "test":
            True,
            "commits": [{
                "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                "distinct": True,
                "message": "Updated via the Open Science Framework",
                "timestamp": "2014-01-08T14:15:51-08:00",
                "url":
                "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                "author": {
                    "name": "Illidan",
                    "email": "*****@*****.**"
                },
                "committer": {
                    "name": "Testor",
                    "email": "*****@*****.**",
                    "username": "******"
                },
                "added": [],
                "removed": [],
                "modified": ["PRJWN3TV"]
            }]
        },
                           content_type="application/json").maybe_follow()
        self.project.reload()
        assert_not_equal(self.project.logs.latest().action,
                         "github_file_updated")

    @mock.patch('addons.github.views.verify_hook_signature')
    def test_hook_callback_remove_file_thro_osf(self, mock_verify):
        url = "/api/v1/project/{0}/github/hook/".format(self.project._id)
        self.app.post_json(url, {
            "test":
            True,
            "commits": [{
                "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                "distinct": True,
                "message": "Deleted via the Open Science Framework",
                "timestamp": "2014-01-08T14:15:51-08:00",
                "url":
                "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                "author": {
                    "name": "Illidan",
                    "email": "*****@*****.**"
                },
                "committer": {
                    "name": "Testor",
                    "email": "*****@*****.**",
                    "username": "******"
                },
                "added": [],
                "removed": ["PRJWN3TV"],
                "modified": []
            }]
        },
                           content_type="application/json").maybe_follow()
        self.project.reload()
        assert_not_equal(self.project.logs.latest().action,
                         "github_file_removed")
Пример #20
0
class TestNodeFilesList(ApiTestCase):

    def setUp(self):
        super(TestNodeFilesList, self).setUp()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        self.private_url = '/{}nodes/{}/files/'.format(
            API_BASE, self.project._id)

        self.user_two = AuthUserFactory()

        self.public_project = ProjectFactory(creator=self.user, is_public=True)
        self.public_url = '/{}nodes/{}/files/'.format(API_BASE, self.public_project._id)

    def add_github(self):
        user_auth = Auth(self.user)
        self.project.add_addon('github', auth=user_auth)
        addon = self.project.get_addon('github')
        addon.repo = 'something'
        addon.user = '******'
        oauth_settings = GitHubAccountFactory()
        oauth_settings.save()
        self.user.add_addon('github')
        self.user.external_accounts.add(oauth_settings)
        self.user.save()
        addon.user_settings = self.user.get_addon('github')
        addon.external_account = oauth_settings
        addon.save()
        self.project.save()
        addon.user_settings.oauth_grants[self.project._id] = {
            oauth_settings._id: []}
        addon.user_settings.save()

    def view_only_link(self):
        private_link = PrivateLinkFactory(creator=self.user)
        private_link.nodes.add(self.project)
        private_link.save()
        return private_link

    def _prepare_mock_wb_response(self, node=None, **kwargs):
        prepare_mock_wb_response(node=node or self.project, **kwargs)

    def test_returns_public_files_logged_out(self):
        res = self.app.get(self.public_url, expect_errors=True)
        assert_equal(res.status_code, 200)
        assert_equal(
            res.json['data'][0]['attributes']['provider'],
            'osfstorage'
        )
        assert_equal(res.content_type, 'application/vnd.api+json')

    def test_returns_public_files_logged_in(self):
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'application/vnd.api+json')
        assert_equal(
            res.json['data'][0]['attributes']['provider'],
            'osfstorage'
        )

    def test_returns_storage_addons_link(self):
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_in('storage_addons', res.json['data'][0]['links'])

    def test_returns_file_data(self):
        fobj = self.project.get_addon(
            'osfstorage').get_root().append_file('NewFile')
        fobj.save()
        res = self.app.get(
            '{}osfstorage/{}'.format(self.private_url, fobj._id), auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_true(isinstance(res.json['data'], dict))
        assert_equal(res.content_type, 'application/vnd.api+json')
        assert_equal(res.json['data']['attributes']['kind'], 'file')
        assert_equal(res.json['data']['attributes']['name'], 'NewFile')

    def test_returns_osfstorage_folder_version_two(self):
        fobj = self.project.get_addon(
            'osfstorage').get_root().append_folder('NewFolder')
        fobj.save()
        res = self.app.get(
            '{}osfstorage/'.format(self.private_url), auth=self.user.auth)
        assert_equal(res.status_code, 200)

    def test_returns_osf_storage_folder_version_two_point_two(self):
        fobj = self.project.get_addon(
            'osfstorage').get_root().append_folder('NewFolder')
        fobj.save()
        res = self.app.get(
            '{}osfstorage/?version=2.2'.format(self.private_url), auth=self.user.auth)
        assert_equal(res.status_code, 200)

    def test_list_returns_folder_data(self):
        fobj = self.project.get_addon(
            'osfstorage').get_root().append_folder('NewFolder')
        fobj.save()
        res = self.app.get(
            '{}osfstorage/'.format(self.private_url, fobj._id), auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 1)
        assert_equal(res.content_type, 'application/vnd.api+json')
        assert_equal(res.json['data'][0]['attributes']['name'], 'NewFolder')

    def test_returns_folder_data(self):
        fobj = self.project.get_addon(
            'osfstorage').get_root().append_folder('NewFolder')
        fobj.save()
        res = self.app.get(
            '{}osfstorage/{}/'.format(self.private_url, fobj._id), auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 0)
        assert_equal(res.content_type, 'application/vnd.api+json')

    def test_returns_private_files_logged_out(self):
        res = self.app.get(self.private_url, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_in('detail', res.json['errors'][0])

    def test_returns_private_files_logged_in_contributor(self):
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'application/vnd.api+json')
        assert_equal(len(res.json['data']), 1)
        assert_equal(
            res.json['data'][0]['attributes']['provider'],
            'osfstorage'
        )

    def test_returns_private_files_logged_in_non_contributor(self):
        res = self.app.get(
            self.private_url,
            auth=self.user_two.auth,
            expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_in('detail', res.json['errors'][0])

    def test_returns_addon_folders(self):
        user_auth = Auth(self.user)
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_equal(len(res.json['data']), 1)
        assert_equal(
            res.json['data'][0]['attributes']['provider'],
            'osfstorage'
        )

        self.project.add_addon('github', auth=user_auth)
        addon = self.project.get_addon('github')
        addon.repo = 'something'
        addon.user = '******'
        oauth_settings = GitHubAccountFactory()
        oauth_settings.save()
        self.user.add_addon('github')
        self.user.external_accounts.add(oauth_settings)
        self.user.save()
        addon.user_settings = self.user.get_addon('github')
        addon.external_account = oauth_settings
        addon.save()
        self.project.save()
        addon.user_settings.oauth_grants[self.project._id] = {
            oauth_settings._id: []}
        addon.user_settings.save()
        res = self.app.get(self.private_url, auth=self.user.auth)
        data = res.json['data']
        providers = [item['attributes']['provider'] for item in data]
        assert_equal(len(data), 2)
        assert_in('github', providers)
        assert_in('osfstorage', providers)

    @responses.activate
    def test_vol_node_files_list(self):
        self._prepare_mock_wb_response(
            provider='github', files=[{'name': 'NewFile'}])
        self.add_github()
        vol = self.view_only_link()
        url = '/{}nodes/{}/files/github/?view_only={}'.format(
            API_BASE, self.project._id, vol.key)
        res = self.app.get(url, auth=self.user_two.auth)
        wb_request = responses.calls[-1].request
        url = furl.furl(wb_request.url)

        assert_equal(url.query, 'meta=True&view_only={}'.format(unicode(vol.key, 'utf-8')))
        assert_equal(res.json['data'][0]['attributes']['name'], 'NewFile')
        assert_equal(res.json['data'][0]['attributes']['provider'], 'github')
        assert_in(vol.key, res.json['data'][0]['links']['info'])
        assert_in(vol.key, res.json['data'][0]['links']['move'])
        assert_in(vol.key, res.json['data'][0]['links']['upload'])
        assert_in(vol.key, res.json['data'][0]['links']['download'])
        assert_in(vol.key, res.json['data'][0]['links']['delete'])

    @responses.activate
    def test_returns_node_files_list(self):
        self._prepare_mock_wb_response(
            provider='github', files=[{'name': 'NewFile'}])
        self.add_github()
        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)

        # test create
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.json['data'][0]['attributes']['name'], 'NewFile')
        assert_equal(res.json['data'][0]['attributes']['provider'], 'github')

        # test get
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.json['data'][0]['attributes']['name'], 'NewFile')
        assert_equal(res.json['data'][0]['attributes']['provider'], 'github')

    @responses.activate
    def test_returns_folder_metadata_not_children(self):
        folder = GithubFolder(
            name='Folder',
            target=self.project,
            path='/Folder/'
        )
        folder.save()
        self._prepare_mock_wb_response(provider='github', files=[{'name': 'Folder'}], path='/Folder/')
        self.add_github()
        url = '/{}nodes/{}/files/github/Folder/'.format(API_BASE, self.project._id)
        res = self.app.get(url, params={'info': ''}, auth=self.user.auth)

        assert_equal(res.status_code, 200)
        assert_equal(res.json['data'][0]['attributes']['kind'], 'folder')
        assert_equal(res.json['data'][0]['attributes']['name'], 'Folder')
        assert_equal(res.json['data'][0]['attributes']['provider'], 'github')

    @responses.activate
    def test_returns_node_file(self):
        self._prepare_mock_wb_response(
            provider='github', files=[{'name': 'NewFile'}],
            folder=False, path='/file')
        self.add_github()
        url = '/{}nodes/{}/files/github/file'.format(
            API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth, headers={
            'COOKIE': 'foo=bar;'  # Webtests doesnt support cookies?
        })
        # test create
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['attributes']['name'], 'NewFile')
        assert_equal(res.json['data']['attributes']['provider'], 'github')

        # test get
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['attributes']['name'], 'NewFile')
        assert_equal(res.json['data']['attributes']['provider'], 'github')

    @responses.activate
    def test_notfound_node_file_returns_folder(self):
        self._prepare_mock_wb_response(
            provider='github', files=[{'name': 'NewFile'}],
            path='/file')
        url = '/{}nodes/{}/files/github/file'.format(
            API_BASE, self.project._id)
        res = self.app.get(
            url, auth=self.user.auth,
            expect_errors=True,
            headers={'COOKIE': 'foo=bar;'}  # Webtests doesnt support cookies?
        )
        assert_equal(res.status_code, 404)

    @responses.activate
    def test_notfound_node_folder_returns_file(self):
        self._prepare_mock_wb_response(
            provider='github', files=[{'name': 'NewFile'}],
            folder=False, path='/')

        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(
            url, auth=self.user.auth,
            expect_errors=True,
            headers={'COOKIE': 'foo=bar;'}  # Webtests doesnt support cookies?
        )
        assert_equal(res.status_code, 404)

    @responses.activate
    def test_waterbutler_server_error_returns_503(self):
        self._prepare_mock_wb_response(status_code=500)
        self.add_github()
        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(
            url, auth=self.user.auth,
            expect_errors=True,
            headers={'COOKIE': 'foo=bar;'}  # Webtests doesnt support cookies?
        )
        assert_equal(res.status_code, 503)

    @responses.activate
    def test_waterbutler_invalid_data_returns_503(self):
        wb_url = waterbutler_api_url_for(self.project._id, _internal=True, provider='github', path='/', meta=True)
        self.add_github()
        responses.add(
            responses.Response(
                responses.GET,
                wb_url,
                body=json.dumps({}),
                status=400
            )
        )
        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 503)

    @responses.activate
    def test_handles_unauthenticated_waterbutler_request(self):
        self._prepare_mock_wb_response(status_code=401)
        self.add_github()
        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_in('detail', res.json['errors'][0])

    @responses.activate
    def test_handles_notfound_waterbutler_request(self):
        invalid_provider = 'gilkjadsflhub'
        self._prepare_mock_wb_response(
            status_code=404, provider=invalid_provider)
        url = '/{}nodes/{}/files/{}/'.format(API_BASE,
                                             self.project._id, invalid_provider)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 404)
        assert_in('detail', res.json['errors'][0])

    def test_handles_request_to_provider_not_configured_on_project(self):
        provider = 'box'
        url = '/{}nodes/{}/files/{}/'.format(
            API_BASE, self.project._id, provider)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_false(self.project.get_addon(provider))
        assert_equal(res.status_code, 404)
        assert_equal(
            res.json['errors'][0]['detail'],
            'The {} provider is not configured for this project.'.format(provider))

    @responses.activate
    def test_handles_bad_waterbutler_request(self):
        wb_url = waterbutler_api_url_for(self.project._id, _internal=True, provider='github', path='/', meta=True)
        responses.add(
            responses.Response(
                responses.GET,
                wb_url,
                json={'bad' : 'json'},
                status=418
            )
        )
        self.add_github()
        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 503)
        assert_in('detail', res.json['errors'][0])

    def test_files_list_contains_relationships_object(self):
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert 'relationships' in res.json['data'][0]
Пример #21
0
class TestNodeFilesListPagination(ApiTestCase):
    def setUp(self):
        super(TestNodeFilesListPagination, self).setUp()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        httpretty.enable()

    def tearDown(self):
        super(TestNodeFilesListPagination, self).tearDown()
        httpretty.disable()
        httpretty.reset()

    def add_github(self):
        user_auth = Auth(self.user)
        self.project.add_addon('github', auth=user_auth)
        addon = self.project.get_addon('github')
        addon.repo = 'something'
        addon.user = '******'
        oauth_settings = GitHubAccountFactory()
        oauth_settings.save()
        self.user.add_addon('github')
        self.user.external_accounts.add(oauth_settings)
        self.user.save()
        addon.user_settings = self.user.get_addon('github')
        addon.external_account = oauth_settings
        addon.save()
        self.project.save()
        addon.user_settings.oauth_grants[self.project._id] = {
            oauth_settings._id: []
        }
        addon.user_settings.save()

    def check_file_order(self, resp):
        previous_file_name = 0
        for file in resp.json['data']:
            int_file_name = int(file['attributes']['name'])
            assert int_file_name > previous_file_name, 'Files were not in order'
            previous_file_name = int_file_name

    def test_node_files_are_sorted_correctly(self):
        prepare_mock_wb_response(node=self.project,
                                 provider='github',
                                 files=[
                                     {
                                         'name': '01',
                                         'path': '/01/',
                                         'materialized': '/01/',
                                         'kind': 'folder'
                                     },
                                     {
                                         'name': '02',
                                         'path': '/02',
                                         'materialized': '/02',
                                         'kind': 'file'
                                     },
                                     {
                                         'name': '03',
                                         'path': '/03/',
                                         'materialized': '/03/',
                                         'kind': 'folder'
                                     },
                                     {
                                         'name': '04',
                                         'path': '/04',
                                         'materialized': '/04',
                                         'kind': 'file'
                                     },
                                     {
                                         'name': '05',
                                         'path': '/05/',
                                         'materialized': '/05/',
                                         'kind': 'folder'
                                     },
                                     {
                                         'name': '06',
                                         'path': '/06',
                                         'materialized': '/06',
                                         'kind': 'file'
                                     },
                                     {
                                         'name': '07',
                                         'path': '/07/',
                                         'materialized': '/07/',
                                         'kind': 'folder'
                                     },
                                     {
                                         'name': '08',
                                         'path': '/08',
                                         'materialized': '/08',
                                         'kind': 'file'
                                     },
                                     {
                                         'name': '09',
                                         'path': '/09/',
                                         'materialized': '/09/',
                                         'kind': 'folder'
                                     },
                                     {
                                         'name': '10',
                                         'path': '/10',
                                         'materialized': '/10',
                                         'kind': 'file'
                                     },
                                     {
                                         'name': '11',
                                         'path': '/11/',
                                         'materialized': '/11/',
                                         'kind': 'folder'
                                     },
                                     {
                                         'name': '12',
                                         'path': '/12',
                                         'materialized': '/12',
                                         'kind': 'file'
                                     },
                                     {
                                         'name': '13',
                                         'path': '/13/',
                                         'materialized': '/13/',
                                         'kind': 'folder'
                                     },
                                     {
                                         'name': '14',
                                         'path': '/14',
                                         'materialized': '/14',
                                         'kind': 'file'
                                     },
                                     {
                                         'name': '15',
                                         'path': '/15/',
                                         'materialized': '/15/',
                                         'kind': 'folder'
                                     },
                                     {
                                         'name': '16',
                                         'path': '/16',
                                         'materialized': '/16',
                                         'kind': 'file'
                                     },
                                     {
                                         'name': '17',
                                         'path': '/17/',
                                         'materialized': '/17/',
                                         'kind': 'folder'
                                     },
                                     {
                                         'name': '18',
                                         'path': '/18',
                                         'materialized': '/18',
                                         'kind': 'file'
                                     },
                                     {
                                         'name': '19',
                                         'path': '/19/',
                                         'materialized': '/19/',
                                         'kind': 'folder'
                                     },
                                     {
                                         'name': '20',
                                         'path': '/20',
                                         'materialized': '/20',
                                         'kind': 'file'
                                     },
                                     {
                                         'name': '21',
                                         'path': '/21/',
                                         'materialized': '/21/',
                                         'kind': 'folder'
                                     },
                                     {
                                         'name': '22',
                                         'path': '/22',
                                         'materialized': '/22',
                                         'kind': 'file'
                                     },
                                     {
                                         'name': '23',
                                         'path': '/23/',
                                         'materialized': '/23/',
                                         'kind': 'folder'
                                     },
                                     {
                                         'name': '24',
                                         'path': '/24',
                                         'materialized': '/24',
                                         'kind': 'file'
                                     },
                                 ])
        self.add_github()
        url = '/{}nodes/{}/files/github/?page[size]=100'.format(
            API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth)
        self.check_file_order(res)
Пример #22
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 = GitHubAccountFactory()
        self.oauth.save()

        self.user.external_accounts.add(self.oauth)
        self.user.save()

        self.node_addon.user_settings = self.user_addon
        self.node_addon.external_account = self.oauth
        self.node_addon.repo = 'Truth'
        self.node_addon.user = '******'
        self.node_addon.save()

        self.user_addon.oauth_grants[self.project._id] = {self.oauth._id: []}
        self.user_addon.save()

    def set_sentry(status):
        def wrapper(func):
            @functools.wraps(func)
            def wrapped(*args, **kwargs):
                enabled, sentry.enabled = sentry.enabled, status
                func(*args, **kwargs)
                sentry.enabled = enabled

            return wrapped

        return wrapper

    with_sentry = set_sentry(True)

    def get_test_file(self):
        version = file_models.FileVersion(identifier='1')
        version.save()
        ret = GithubFile(
            name='Test',
            node=self.project,
            path='/test/Test',
            materialized_path='/test/Test',
        )
        ret.save()
        ret.versions.add(version)
        return ret

    def get_second_test_file(self):
        version = file_models.FileVersion(identifier='1')
        version.save()
        ret = GithubFile(
            name='Test2',
            node=self.project,
            path='/test/Test2',
            materialized_path='/test/Test2',
        )
        ret.save()
        ret.versions.add(version)
        return ret

    def get_mako_return(self):
        ret = serialize_node(self.project, Auth(self.user), primary=True)
        ret.update({
            'error': '',
            'provider': '',
            'file_path': '',
            'sharejs_uuid': '',
            'private': '',
            'urls': {
                'files': '',
                'render': '',
                'sharejs': '',
                'mfr': '',
                'profile_image': '',
                'external': '',
                'archived_from': '',
            },
            'size': '',
            'extra': '',
            'file_name': '',
            'materialized_path': '',
            'file_id': '',
        })
        ret.update(rubeus.collect_addon_assets(self.project))
        return ret

    def test_redirects_to_guid(self):
        file_node = self.get_test_file()
        guid = file_node.get_guid(create=True)

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

        assert_equals(resp.status_code, 302)
        assert_equals(resp.location, 'http://*****:*****@mock.patch('addons.base.views.addon_view_file')
    def test_action_view_calls_view_file(self, mock_view_file):
        self.user.reload()
        self.project.reload()

        file_node = self.get_test_file()
        guid = file_node.get_guid(create=True)

        mock_view_file.return_value = self.get_mako_return()

        self.app.get('/{}/?action=view'.format(guid._id), auth=self.user.auth)

        args, kwargs = mock_view_file.call_args
        assert_equals(kwargs, {})
        assert_equals(args[0].user._id, self.user._id)
        assert_equals(args[1], self.project)
        assert_equals(args[2], file_node)
        assert_true(isinstance(args[3], file_node.touch(None).__class__))

    @mock.patch('addons.base.views.addon_view_file')
    def test_no_action_calls_view_file(self, mock_view_file):
        self.user.reload()
        self.project.reload()

        file_node = self.get_test_file()
        guid = file_node.get_guid(create=True)

        mock_view_file.return_value = self.get_mako_return()

        self.app.get('/{}/'.format(guid._id), auth=self.user.auth)

        args, kwargs = mock_view_file.call_args
        assert_equals(kwargs, {})
        assert_equals(args[0].user._id, self.user._id)
        assert_equals(args[1], self.project)
        assert_equals(args[2], file_node)
        assert_true(isinstance(args[3], file_node.touch(None).__class__))

    def test_download_create_guid(self):
        file_node = self.get_test_file()
        assert_is(file_node.get_guid(), None)

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

        assert_true(file_node.get_guid())

    def test_view_file_does_not_delete_file_when_requesting_invalid_version(self):
        with mock.patch('addons.github.models.NodeSettings.is_private',
                        new_callable=mock.PropertyMock) as mock_is_private:
            mock_is_private.return_value = False

            file_node = self.get_test_file()
            assert_is(file_node.get_guid(), None)

            url = self.project.web_url_for(
                'addon_view_or_download_file',
                path=file_node.path.strip('/'),
                provider='github',
            )
            # First view generated GUID
            self.app.get(url, auth=self.user.auth)

            self.app.get(url + '?version=invalid', auth=self.user.auth, expect_errors=True)

            assert_is_not_none(BaseFileNode.load(file_node._id))
            assert_is_none(TrashedFileNode.load(file_node._id))

    def test_unauthorized_addons_raise(self):
        path = 'cloudfiles'
        self.node_addon.user_settings = None
        self.node_addon.save()

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

        assert_equals(resp.status_code, 401)

    def test_nonstorage_addons_raise(self):
        resp = self.app.get(
            self.project.web_url_for(
                'addon_view_or_download_file',
                path='sillywiki',
                provider='wiki',
                action='download'
            ),
            auth=self.user.auth,
            expect_errors=True
        )

        assert_equals(resp.status_code, 400)

    def test_head_returns_url_and_redriect(self):
        file_node = self.get_test_file()
        guid = file_node.get_guid(create=True)

        resp = self.app.head('/{}/'.format(guid._id), auth=self.user.auth)
        location = furl.furl(resp.location)
        assert_equals(resp.status_code, 302)
        assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, version=''))

    def test_head_returns_url_with_version_and_redirect(self):
        file_node = self.get_test_file()
        guid = file_node.get_guid(create=True)

        resp = self.app.head('/{}/?revision=1&foo=bar'.format(guid._id), auth=self.user.auth)
        location = furl.furl(resp.location)
        # Note: version is added but us but all other url params are added as well
        assert_equals(resp.status_code, 302)
        assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, revision=1, version='', foo='bar'))

    def test_nonexistent_addons_raise(self):
        path = 'cloudfiles'
        self.project.delete_addon('github', Auth(self.user))
        self.project.save()

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

        assert_equals(resp.status_code, 400)

    def test_unauth_addons_raise(self):
        path = 'cloudfiles'
        self.node_addon.user_settings = None
        self.node_addon.save()

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

        assert_equals(resp.status_code, 401)

    def test_delete_action_creates_trashed_file_node(self):
        file_node = self.get_test_file()
        payload = {
            'provider': file_node.provider,
            'metadata': {
                'path': '/test/Test',
                'materialized': '/test/Test'
            }
        }
        views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload)
        assert_false(GithubFileNode.load(file_node._id))
        assert_true(TrashedFileNode.load(file_node._id))

    def test_delete_action_for_folder_deletes_subfolders_and_creates_trashed_file_nodes(self):
        file_node = self.get_test_file()
        subfolder = GithubFolder(
            name='folder',
            node=self.project,
            path='/test/folder/',
            materialized_path='/test/folder/',
        )
        subfolder.save()
        payload = {
            'provider': file_node.provider,
            'metadata': {
                'path': '/test/',
                'materialized': '/test/'
            }
        }
        views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload)
        assert_false(GithubFileNode.load(subfolder._id))
        assert_true(TrashedFileNode.load(file_node._id))

    @mock.patch('website.archiver.tasks.archive')
    def test_archived_from_url(self, mock_archive):
        file_node = self.get_test_file()
        second_file_node = self.get_second_test_file()
        file_node.copied_from = second_file_node

        registered_node = self.project.register_node(
            schema=get_default_metaschema(),
            auth=Auth(self.user),
            data=None,
        )

        archived_from_url = views.get_archived_from_url(registered_node, file_node)
        view_url = self.project.web_url_for('addon_view_or_download_file', provider=file_node.provider, path=file_node.copied_from._id)
        assert_true(archived_from_url)
        assert_urls_equal(archived_from_url, view_url)

    @mock.patch('website.archiver.tasks.archive')
    def test_archived_from_url_without_copied_from(self, mock_archive):
        file_node = self.get_test_file()

        registered_node = self.project.register_node(
            schema=get_default_metaschema(),
            auth=Auth(self.user),
            data=None,
        )
        archived_from_url = views.get_archived_from_url(registered_node, file_node)
        assert_false(archived_from_url)

    @mock.patch('website.archiver.tasks.archive')
    def test_copied_from_id_trashed(self, mock_archive):
        file_node = self.get_test_file()
        second_file_node = self.get_second_test_file()
        file_node.copied_from = second_file_node
        self.project.register_node(
            schema=get_default_metaschema(),
            auth=Auth(self.user),
            data=None,
        )
        trashed_node = second_file_node.delete()
        assert_false(trashed_node.copied_from)

    @mock.patch('website.archiver.tasks.archive')
    def test_missing_modified_date_in_file_data(self, mock_archive):
        file_node = self.get_test_file()
        file_data = {
            'name': 'Test File Update',
            'materialized': file_node.materialized_path,
            'modified': None
        }
        file_node.update(revision=None, data=file_data)
        assert_equal(len(file_node.history), 1)
        assert_equal(file_node.history[0], file_data)

    @mock.patch('website.archiver.tasks.archive')
    def test_missing_modified_date_in_file_history(self, mock_archive):
        file_node = self.get_test_file()
        file_node.history.append({'modified': None})
        file_data = {
            'name': 'Test File Update',
            'materialized': file_node.materialized_path,
            'modified': None
        }
        file_node.update(revision=None, data=file_data)
        assert_equal(len(file_node.history), 2)
        assert_equal(file_node.history[1], file_data)

    @with_sentry
    @mock.patch('framework.sentry.sentry.captureMessage')
    def test_update_logs_to_sentry_when_called_with_disordered_metadata(self, mock_capture):
        file_node = self.get_test_file()
        file_node.history.append({'modified': parse_date(
                '2017-08-22T13:54:32.100900',
                ignoretz=True,
                default=timezone.now()  # Just incase nothing can be parsed
            )})
        data = {
            'name': 'a name',
            'materialized': 'materialized',
            'modified': '2016-08-22T13:54:32.100900'
        }
        file_node.update(revision=None, user=None, data=data)
        mock_capture.assert_called_with(unicode('update() receives metatdata older than the newest entry in file history.'), extra={'session': {}})
Пример #23
0
class TestAddonLogs(OsfTestCase):

    def setUp(self):
        super(TestAddonLogs, self).setUp()
        self.user = AuthUserFactory()
        self.auth_obj = Auth(user=self.user)
        self.node = ProjectFactory(creator=self.user)
        self.session = Session(data={'auth_user_id': self.user._id})
        self.session.save()
        self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id)
        self.configure_addon()

    def configure_addon(self):
        self.user.add_addon('github')
        self.user_addon = self.user.get_addon('github')
        self.oauth_settings = GitHubAccountFactory(display_name='john')
        self.oauth_settings.save()
        self.user.external_accounts.add(self.oauth_settings)
        self.user.save()
        self.node.add_addon('github', self.auth_obj)
        self.node_addon = self.node.get_addon('github')
        self.node_addon.user = '******'
        self.node_addon.repo = 'youre-my-best-friend'
        self.node_addon.user_settings = self.user_addon
        self.node_addon.external_account = self.oauth_settings
        self.node_addon.save()
        self.user_addon.oauth_grants[self.node._id] = {self.oauth_settings._id: []}
        self.user_addon.save()

    def configure_osf_addon(self):
        self.project = ProjectFactory(creator=self.user)
        self.node_addon = self.project.get_addon('osfstorage')
        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 = self.node.logs.count()
        self.app.put_json(url, payload, headers={'Content-Type': 'application/json'})
        self.node.reload()
        assert_equal(self.node.logs.count(), 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 = self.node.logs.count()
        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(self.node.logs.count(), 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 = self.node.logs.count()
        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(self.node.logs.count(), 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 = node.logs.count()
        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(node.logs.count(), 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 = self.node.logs.count()
        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(self.node.logs.count(), nlogs)

    def test_action_file_rename(self):
        url = self.node.api_url_for('create_waterbutler_log')
        payload = self.build_payload(
            action='rename',
            metadata={
                'path': 'foo',
            },
            source={
                'materialized': 'foo',
                'provider': 'github',
                'node': {'_id': self.node._id},
                'name': 'new.txt',
                'kind': 'file',
            },
            destination={
                'path': 'foo',
                'materialized': 'foo',
                'provider': 'github',
                'node': {'_id': self.node._id},
                'name': 'old.txt',
                'kind': 'file',
            },
        )
        self.app.put_json(
            url,
            payload,
            headers={'Content-Type': 'application/json'}
        )
        self.node.reload()

        assert_equal(
            self.node.logs.latest().action,
            'github_addon_file_renamed',
        )

    def test_action_downloads(self):
        url = self.node.api_url_for('create_waterbutler_log')
        download_actions=('download_file', 'download_zip')
        for action in download_actions:
            payload = self.build_payload(metadata={'path': 'foo'}, action=action)
            nlogs = self.node.logs.count()
            res = self.app.put_json(
                url,
                payload,
                headers={'Content-Type': 'application/json'},
                expect_errors=False,
            )
            assert_equal(res.status_code, 200)

        self.node.reload()
        assert_equal(self.node.logs.count(), nlogs)

    def test_add_file_osfstorage_log(self):
        self.configure_osf_addon()
        path = 'pizza'
        url = self.node.api_url_for('create_waterbutler_log')
        payload = self.build_payload(metadata={'materialized': path, 'kind': 'file', 'path': path})
        nlogs = self.node.logs.count()
        self.app.put_json(url, payload, headers={'Content-Type': 'application/json'})
        self.node.reload()
        assert_equal(self.node.logs.count(), nlogs + 1)
        assert('urls' in self.node.logs.filter(action='osf_storage_file_added')[0].params)

    def test_add_folder_osfstorage_log(self):
        self.configure_osf_addon()
        path = 'pizza'
        url = self.node.api_url_for('create_waterbutler_log')
        payload = self.build_payload(metadata={'materialized': path, 'kind': 'folder', 'path': path})
        nlogs = self.node.logs.count()
        self.app.put_json(url, payload, headers={'Content-Type': 'application/json'})
        self.node.reload()
        assert_equal(self.node.logs.count(), nlogs + 1)
        assert('urls' not in self.node.logs.filter(action='osf_storage_file_added')[0].params)
class TestAddonCount(OsfTestCase):
    def setUp(self):
        super(TestAddonCount, self).setUp()
        self.user = AuthUserFactory()
        self.node = ProjectFactory(creator=self.user)
        self.user.add_addon('github')
        self.user_addon = self.user.get_addon('github')

        self.external_account = GitHubAccountFactory(display_name='hmoco1')

        self.user_settings = self.user.get_or_add_addon('github')

        self.user_settings.save()
        self.user.external_accounts.add(self.external_account)
        self.user.save()
        self.node.add_addon('github', Auth(self.user))
        self.node_addon = self.node.get_addon('github')
        self.node_addon.user = self.user.fullname
        self.node_addon.repo = '29 #Strafford APTS'
        self.node_addon.user_settings = self.user_addon
        self.node_addon.external_account = self.external_account
        self.node_addon.save()

        self.user_settings.grant_oauth_access(
            node=self.node,
            external_account=self.external_account,
        )

    def test_run_for_all_addon(self):
        results = AddonSnapshot().get_events()
        names = [res['provider']['name'] for res in results]
        for addon in ADDONS_AVAILABLE:
            assert_in(addon.short_name, names)

    def test_one_user_one_node_one_addon(self):
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['users']['enabled'], 1)
        assert_equal(github_res['nodes']['total'], 1)

    def test_one_user_one_node_one_addon_one_node_linked(self):
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['users']['enabled'], 1)
        assert_equal(github_res['nodes']['total'], 1)

    def test_one_user_with_multiple_githubs(self):
        oauth_settings2 = GitHubAccountFactory(display_name='hmoco2')
        oauth_settings2.save()
        self.user.external_accounts.add(oauth_settings2)
        self.user.save()
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['users']['enabled'], 1)

    def test_one_user_with_multiple_addons(self):
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        googledrive_res = [res for res in results if res['provider']['name'] == 'googledrive'][0]
        assert_equal(github_res['users']['enabled'], 1)
        assert_equal(googledrive_res['users']['enabled'], 0)

        self.user.add_addon('googledrive')
        oauth_settings = GoogleDriveAccountFactory()
        oauth_settings.save()
        self.user.external_accounts.add(oauth_settings)
        self.user.save()
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        googledrive_res = [res for res in results if res['provider']['name'] == 'googledrive'][0]
        assert_equal(github_res['users']['enabled'], 1)
        assert_equal(googledrive_res['users']['enabled'], 1)

    def test_many_users_each_with_a_different_github(self):
        user = AuthUserFactory()
        user.add_addon('github')
        oauth_settings2 = GitHubAccountFactory(display_name='hmoco2')
        oauth_settings2.save()
        user.external_accounts.add(oauth_settings2)
        user.save()
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['users']['enabled'], 2)
        assert_equal(github_res['users']['authorized'], 1)
        assert_equal(github_res['users']['linked'], 1)

    def test_many_users_each_with_the_same_github_enabled(self):
        user = AuthUserFactory()
        user.add_addon('github')
        user.external_accounts.add(self.external_account)
        user.save()
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['users']['enabled'], 2)

    def test_github_enabled_not_linked_or_authorized(self):
        user = AuthUserFactory()
        user.add_addon('github')
        user.external_accounts.add(self.external_account)
        user.save()
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['users']['enabled'], 2)
        assert_equal(github_res['users']['authorized'], 1)
        assert_equal(github_res['users']['linked'], 1)

    def test_one_node_with_multiple_addons(self):
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        googledrive_res = [res for res in results if res['provider']['name'] == 'googledrive'][0]
        assert_equal(github_res['nodes']['total'], 1)
        assert_equal(googledrive_res['nodes']['total'], 0)

        self.user.add_addon('googledrive')
        user_addon = self.user.get_addon('googledrive')
        oauth_settings = GoogleDriveAccountFactory()
        oauth_settings.save()
        self.user.external_accounts.add(oauth_settings)
        self.user.save()
        self.node.add_addon('googledrive', Auth(self.user))
        node_addon = self.node.get_addon('googledrive')
        node_addon.user = self.user.fullname
        node_addon.user_settings = user_addon
        node_addon.external_account = oauth_settings
        node_addon.save()
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        googledrive_res = [res for res in results if res['provider']['name'] == 'googledrive'][0]
        assert_equal(github_res['nodes']['total'], 1)
        assert_equal(googledrive_res['nodes']['total'], 1)

    def test_many_nodes_with_one_addon(self):
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['nodes']['total'], 1)

        node = ProjectFactory(creator=self.user)
        node.add_addon('github', Auth(self.user))
        node_addon = node.get_addon('github')
        node_addon.user = self.user.fullname
        node_addon.repo = '8 (circle)'
        node_addon.user_settings = self.user_addon
        node_addon.external_account = self.external_account
        node_addon.save()
        node.save()

        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['nodes']['total'], 2)

    def test_node_count_deleted_addon(self):
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['nodes']['deleted'], 0)

        node = ProjectFactory(creator=self.user)
        node.add_addon('github', Auth(self.user))
        node_addon = node.get_addon('github')
        node_addon.delete()

        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['nodes']['deleted'], 1)

    def test_node_count_disconected_addon(self):
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['nodes']['disconnected'], 0)

        node = ProjectFactory(creator=self.user)
        node.add_addon('github', Auth(self.user))
        node_addon = node.get_addon('github')
        node_addon.external_account = None
        node_addon.save()

        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(github_res['nodes']['disconnected'], 1)

    def test_all_users_have_wiki_osfstorage_enabled(self):
        all_user_count = OSFUser.objects.all().count()
        results = AddonSnapshot().get_events()
        osfstorage_res = [res for res in results if res['provider']['name'] == 'osfstorage'][0]
        wiki_res = [res for res in results if res['provider']['name'] == 'osfstorage'][0]

        assert_equal(osfstorage_res['users']['enabled'], all_user_count)
        assert_equal(wiki_res['users']['enabled'], all_user_count)

    def test_wiki_deleted_shows_as_deleted(self):
        node = ProjectFactory(creator=self.user)
        node.delete_addon('wiki', auth=Auth(self.user))

        results = AddonSnapshot().get_events()
        wiki_res = [res for res in results if res['provider']['name'] == 'wiki'][0]

        assert_equal(wiki_res['nodes']['deleted'], 1)

    def test_node_settings_has_no_owner_not_connected(self):
        self.node_addon.owner = None
        self.node_addon.save()

        results = AddonSnapshot().get_events()
        storage_res = [res for res in results if res['provider']['name'] == 'github'][0]
        assert_equal(storage_res['nodes']['connected'], 0)
Пример #25
0
class TestCreateBucket(S3AddonTestCase, OsfTestCase):
    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('eu-central-1'))
        assert_true(validate_bucket_location('ca-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('sa-east-1'))
        assert_true(validate_bucket_location('eu-west-1'))
        assert_true(validate_bucket_location('eu-west-2'))

    @mock.patch('addons.s3.views.utils.create_bucket')
    @mock.patch('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('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('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"}'
        )
Пример #26
0
class TestBitbucketSettings(OsfTestCase):

    def setUp(self):

        super(TestBitbucketSettings, self).setUp()
        self.bitbucket = create_mock_bitbucket(user='******', private=False)
        self.project = ProjectFactory()
        self.project.save()
        self.auth = self.project.creator.auth
        self.consolidated_auth = Auth(user=self.project.creator)

        self.project.add_addon('bitbucket', auth=self.consolidated_auth)
        self.project.creator.add_addon('bitbucket')
        self.node_settings = self.project.get_addon('bitbucket')
        self.user_settings = self.project.creator.get_addon('bitbucket')
        self.node_settings.user_settings = self.user_settings
        self.node_settings.user = '******'
        self.node_settings.repo = 'Sheer-Heart-Attack'
        self.node_settings.save()

    @mock.patch('addons.bitbucket.api.BitbucketClient.repo')
    @mock.patch('addons.bitbucket.models.NodeSettings.external_account')
    def test_link_repo(self, mock_account, mock_repo):
        bitbucket_mock = self.bitbucket
        mock_account.return_value = mock.Mock()
        mock_repo.return_value = bitbucket_mock.repo.return_value

        url = self.project.api_url + 'bitbucket/settings/'
        self.app.post_json(
            url,
            {
                'bitbucket_user': '******',
                'bitbucket_repo': 'night at the opera',
            },
            auth=self.auth
        ).maybe_follow()

        self.project.reload()
        self.node_settings.reload()

        assert_equal(self.node_settings.user, 'queen')
        assert_equal(self.node_settings.repo, 'night at the opera')
        assert_equal(self.project.logs.latest().action, 'bitbucket_repo_linked')

    @mock.patch('addons.bitbucket.api.BitbucketClient.repo')
    @mock.patch('addons.bitbucket.models.NodeSettings.external_account')
    def test_link_repo_no_change(self, mock_account, mock_repo):
        bitbucket_mock = self.bitbucket
        mock_account.return_value = mock.Mock()
        mock_repo.return_value = bitbucket_mock.repo.return_value

        log_count = self.project.logs.count()

        url = self.project.api_url + 'bitbucket/settings/'
        self.app.post_json(
            url,
            {
                'bitbucket_user': '******',
                'bitbucket_repo': 'Sheer-Heart-Attack',
            },
            auth=self.auth
        ).maybe_follow()

        self.project.reload()
        self.node_settings.reload()

        assert_equal(self.project.logs.count(), log_count)

    @mock.patch('addons.bitbucket.api.BitbucketClient.repo')
    @mock.patch('addons.bitbucket.models.NodeSettings.external_account')
    def test_link_repo_non_existent(self, mock_account, mock_repo):
        mock_account.return_value = mock.Mock()
        mock_repo.return_value = None

        url = self.project.api_url + 'bitbucket/settings/'
        res = self.app.post_json(
            url,
            {
                'bitbucket_user': '******',
                'bitbucket_repo': 'night at the opera',
            },
            auth=self.auth,
            expect_errors=True
        ).maybe_follow()

        assert_equal(res.status_code, 400)

    @mock.patch('addons.bitbucket.api.BitbucketClient.branches')
    def test_link_repo_registration(self, mock_branches):
        bitbucket_mock = self.bitbucket
        mock_branches.return_value = bitbucket_mock.branches.return_value

        registration = self.project.register_node(
            schema=get_default_metaschema(),
            auth=self.consolidated_auth,
            data=''
        )

        url = registration.api_url + 'bitbucket/settings/'
        res = self.app.post_json(
            url,
            {
                'bitbucket_user': '******',
                'bitbucket_repo': 'night at the opera',
            },
            auth=self.auth,
            expect_errors=True
        ).maybe_follow()

        assert_equal(res.status_code, 400)

    def test_deauthorize(self):

        url = self.project.api_url + 'bitbucket/user_auth/'

        self.app.delete(url, auth=self.auth).maybe_follow()

        self.project.reload()
        self.node_settings.reload()
        assert_equal(self.node_settings.user, None)
        assert_equal(self.node_settings.repo, None)
        assert_equal(self.node_settings.user_settings, None)

        assert_equal(self.project.logs.latest().action, 'bitbucket_node_deauthorized')
Пример #27
0
class TestGithubViews(OsfTestCase):

    def setUp(self):
        super(TestGithubViews, self).setUp()
        self.user = AuthUserFactory()
        self.consolidated_auth = Auth(user=self.user)

        self.project = ProjectFactory(creator=self.user)
        self.non_authenticator = UserFactory()
        self.project.add_contributor(
            contributor=self.non_authenticator,
            auth=self.consolidated_auth,
        )
        self.project.creator.add_addon('github')
        self.project.creator.external_accounts.add(GitHubAccountFactory())
        self.project.creator.save()
        self.project.save()
        self.project.add_addon('github', auth=self.consolidated_auth)

        self.github = create_mock_github(user='******', private=False)

        self.node_settings = self.project.get_addon('github')
        self.node_settings.user_settings = self.project.creator.get_addon('github')
        # Set the node addon settings to correspond to the values of the mock repo
        self.node_settings.user = self.github.repo.return_value.owner.login
        self.node_settings.repo = self.github.repo.return_value.name
        self.node_settings.save()

    def _get_sha_for_branch(self, branch=None, mock_branches=None):
        github_mock = self.github
        if mock_branches is None:
            mock_branches = github_mock.branches
        if branch is None:  # Get default branch name
            branch = self.github.repo.return_value.default_branch
        for each in mock_branches.return_value:
            if each.name == branch:
                branch_sha = each.commit.sha
        return branch_sha

    # Tests for _get_refs
    @mock.patch('addons.github.api.GitHubClient.branches')
    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_get_refs_defaults(self, mock_repo, mock_branches):
        github_mock = self.github
        mock_repo.return_value = github_mock.repo.return_value
        mock_branches.return_value = github_mock.branches.return_value
        branch, sha, branches = utils.get_refs(self.node_settings)
        assert_equal(
            branch,
            github_mock.repo.return_value.default_branch
        )
        assert_equal(sha, self._get_sha_for_branch(branch=None))  # Get refs for default branch
        assert_equal(
            branches,
            github_mock.branches.return_value
        )

    @mock.patch('addons.github.api.GitHubClient.branches')
    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_get_refs_branch(self, mock_repo, mock_branches):
        github_mock = self.github
        mock_repo.return_value = github_mock.repo.return_value
        mock_branches.return_value = github_mock.branches.return_value
        branch, sha, branches = utils.get_refs(self.node_settings, 'master')
        assert_equal(branch, 'master')
        branch_sha = self._get_sha_for_branch('master')
        assert_equal(sha, branch_sha)
        assert_equal(
            branches,
            github_mock.branches.return_value
        )

    def test_before_fork(self):
        url = self.project.api_url + 'fork/before/'
        res = self.app.get(url, auth=self.user.auth).maybe_follow()
        assert_equal(len(res.json['prompts']), 1)

    def test_get_refs_sha_no_branch(self):
        with assert_raises(HTTPError):
            utils.get_refs(self.node_settings, sha='12345')

    def test_get_refs_registered_missing_branch(self):
        github_mock = self.github
        self.node_settings.registration_data = {
            'branches': [
                branch.to_json()
                for branch in github_mock.branches.return_value
            ]
        }
        with mock.patch('osf.models.node.AbstractNode.is_registration', new_callable=mock.PropertyMock) as mock_is_reg:
            mock_is_reg.return_value = True
            with assert_raises(HTTPError):
                utils.get_refs(self.node_settings, branch='nothere')

    # Tests for _check_permissions
    # make a user with no authorization; make sure check_permissions returns false
    def test_permissions_no_auth(self):
        github_mock = self.github
        # project is set to private right now
        connection = github_mock
        non_authenticated_user = UserFactory()
        non_authenticated_auth = Auth(user=non_authenticated_user)
        branch = 'master'
        assert_false(check_permissions(self.node_settings, non_authenticated_auth, connection, branch))

    # make a repository that doesn't allow push access for this user;
    # make sure check_permissions returns false
    @mock.patch('addons.github.models.UserSettings.has_auth')
    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_permissions_no_access(self, mock_repo, mock_has_auth):
        github_mock = self.github
        mock_has_auth.return_value = True
        connection = github_mock
        branch = 'master'
        mock_repository = mock.NonCallableMock()
        mock_repository.user = '******'
        mock_repository.repo = 'mock-repo'
        mock_repository.to_json.return_value = {
            'user': '******',
            'repo': 'mock-repo',
            'permissions': {
                'push': False,  # this is key
            },
        }
        mock_repo.return_value = mock_repository
        assert_false(check_permissions(self.node_settings, self.consolidated_auth, connection, branch, repo=mock_repository))

    # make a branch with a different commit than the commit being passed into check_permissions
    @mock.patch('addons.github.models.UserSettings.has_auth')
    def test_permissions_not_head(self, mock_has_auth):
        github_mock = self.github
        mock_has_auth.return_value = True
        connection = github_mock
        mock_branch = mock.NonCallableMock()
        mock_branch.commit.sha = '67890'
        sha = '12345'
        assert_false(check_permissions(self.node_settings, self.consolidated_auth, connection, mock_branch, sha=sha))

    # make sure permissions are not granted for editing a registration
    @mock.patch('addons.github.models.UserSettings.has_auth')
    def test_permissions(self, mock_has_auth):
        github_mock = self.github
        mock_has_auth.return_value = True
        connection = github_mock
        with mock.patch('osf.models.node.AbstractNode.is_registration', new_callable=mock.PropertyMock) as mock_is_reg:
            mock_is_reg.return_value = True
            assert_false(check_permissions(self.node_settings, self.consolidated_auth, connection, 'master'))

    def check_hook_urls(self, urls, node, path, sha):
        url = node.web_url_for('addon_view_or_download_file', path=path, provider='github')
        expected_urls = {
            'view': '{0}?ref={1}'.format(url, sha),
            'download': '{0}?action=download&ref={1}'.format(url, sha)
        }

        assert_equal(urls['view'], expected_urls['view'])
        assert_equal(urls['download'], expected_urls['download'])

    @mock.patch('addons.github.views.verify_hook_signature')
    def test_hook_callback_add_file_not_thro_osf(self, mock_verify):
        url = '/api/v1/project/{0}/github/hook/'.format(self.project._id)
        timestamp = str(timezone.now())
        self.app.post_json(
            url,
            {
                "test": True,
                "commits": [{
                    "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                    "distinct": True,
                    "message": "foo",
                    "timestamp": timestamp,
                    "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                    "author": {"name": "Illidan", "email": "*****@*****.**"},
                    "committer": {"name": "Testor", "email": "*****@*****.**", "username": "******"},
                    "added": ["PRJWN3TV"],
                    "removed": [],
                    "modified": [],
                }]
            },
            content_type="application/json",
        ).maybe_follow()
        self.project.reload()
        assert_equal(self.project.logs.latest().action, "github_file_added")
        urls = self.project.logs.latest().params['urls']
        self.check_hook_urls(
            urls,
            self.project,
            path='PRJWN3TV',
            sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
        )

    @mock.patch('addons.github.views.verify_hook_signature')
    def test_hook_callback_modify_file_not_thro_osf(self, mock_verify):
        url = "/api/v1/project/{0}/github/hook/".format(self.project._id)
        timestamp = str(timezone.now())
        self.app.post_json(
            url,
            {"test": True,
                 "commits": [{"id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                              "distinct": True,
                              "message": " foo",
                              "timestamp": timestamp,
                              "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                              "author": {"name": "Illidan", "email": "*****@*****.**"},
                              "committer": {"name": "Testor", "email": "*****@*****.**",
                                            "username": "******"},
                              "added": [], "removed":[], "modified":["PRJWN3TV"]}]},
            content_type="application/json").maybe_follow()
        self.project.reload()
        assert_equal(self.project.logs.latest().action, "github_file_updated")
        urls = self.project.logs.latest().params['urls']
        self.check_hook_urls(
            urls,
            self.project,
            path='PRJWN3TV',
            sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
        )

    @mock.patch('addons.github.views.verify_hook_signature')
    def test_hook_callback_remove_file_not_thro_osf(self, mock_verify):
        url = "/api/v1/project/{0}/github/hook/".format(self.project._id)
        timestamp = str(timezone.now())
        self.app.post_json(
            url,
            {"test": True,
             "commits": [{"id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                          "distinct": True,
                          "message": "foo",
                          "timestamp": timestamp,
                          "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                          "author": {"name": "Illidan", "email": "*****@*****.**"},
                          "committer": {"name": "Testor", "email": "*****@*****.**", "username": "******"},
                          "added": [], "removed": ["PRJWN3TV"], "modified":[]}]},
            content_type="application/json").maybe_follow()
        self.project.reload()
        assert_equal(self.project.logs.latest().action, "github_file_removed")
        urls = self.project.logs.latest().params['urls']
        assert_equal(urls, {})

    @mock.patch('addons.github.views.verify_hook_signature')
    def test_hook_callback_add_file_thro_osf(self, mock_verify):
        url = "/api/v1/project/{0}/github/hook/".format(self.project._id)
        self.app.post_json(
            url,
            {"test": True,
             "commits": [{"id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                          "distinct": True,
                          "message": "Added via the Open Science Framework",
                          "timestamp": "2014-01-08T14:15:51-08:00",
                          "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                          "author": {"name": "Illidan", "email": "*****@*****.**"},
                          "committer": {"name": "Testor", "email": "*****@*****.**", "username": "******"},
                          "added": ["PRJWN3TV"], "removed":[], "modified":[]}]},
            content_type="application/json").maybe_follow()
        self.project.reload()
        assert_not_equal(self.project.logs.latest().action, "github_file_added")

    @mock.patch('addons.github.views.verify_hook_signature')
    def test_hook_callback_modify_file_thro_osf(self, mock_verify):
        url = "/api/v1/project/{0}/github/hook/".format(self.project._id)
        self.app.post_json(
            url,
            {"test": True,
             "commits": [{"id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                          "distinct": True,
                          "message": "Updated via the Open Science Framework",
                          "timestamp": "2014-01-08T14:15:51-08:00",
                          "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                          "author": {"name": "Illidan", "email": "*****@*****.**"},
                          "committer": {"name": "Testor", "email": "*****@*****.**", "username": "******"},
                          "added": [], "removed":[], "modified":["PRJWN3TV"]}]},
            content_type="application/json").maybe_follow()
        self.project.reload()
        assert_not_equal(self.project.logs.latest().action, "github_file_updated")

    @mock.patch('addons.github.views.verify_hook_signature')
    def test_hook_callback_remove_file_thro_osf(self, mock_verify):
        url = "/api/v1/project/{0}/github/hook/".format(self.project._id)
        self.app.post_json(
            url,
            {"test": True,
             "commits": [{"id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                          "distinct": True,
                          "message": "Deleted via the Open Science Framework",
                          "timestamp": "2014-01-08T14:15:51-08:00",
                          "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce",
                          "author": {"name": "Illidan", "email": "*****@*****.**"},
                          "committer": {"name": "Testor", "email": "*****@*****.**", "username": "******"},
                          "added": [], "removed":["PRJWN3TV"], "modified":[]}]},
            content_type="application/json").maybe_follow()
        self.project.reload()
        assert_not_equal(self.project.logs.latest().action, "github_file_removed")
Пример #28
0
class TestNodeLogList(ApiTestCase):
    def setUp(self):
        super(TestNodeLogList, self).setUp()
        self.user = AuthUserFactory()
        self.contrib = AuthUserFactory()
        self.creator = AuthUserFactory()
        self.user_auth = Auth(self.user)
        self.NodeLogFactory = ProjectFactory()
        self.pointer = ProjectFactory()

        self.private_project = ProjectFactory(is_public=False,
                                              creator=self.user)
        self.private_url = '/{}nodes/{}/logs/?version=2.2'.format(
            API_BASE, self.private_project._id)

        self.public_project = ProjectFactory(is_public=True, creator=self.user)
        self.public_url = '/{}nodes/{}/logs/?version=2.2'.format(
            API_BASE, self.public_project._id)

    def test_add_tag(self):
        user_auth = Auth(self.user)
        self.public_project.add_tag("Jeff Spies", auth=user_auth)
        assert_equal("tag_added", self.public_project.logs.latest().action)
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), self.public_project.logs.count())
        assert_equal(res.json['data'][API_LATEST]['attributes']['action'],
                     'tag_added')
        assert_equal("Jeff Spies",
                     self.public_project.logs.latest().params['tag'])

    def test_remove_tag(self):
        user_auth = Auth(self.user)
        self.public_project.add_tag("Jeff Spies", auth=user_auth)
        assert_equal("tag_added", self.public_project.logs.latest().action)
        self.public_project.remove_tag("Jeff Spies", auth=self.user_auth)
        assert_equal("tag_removed", self.public_project.logs.latest().action)
        res = self.app.get(self.public_url, auth=self.user)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), self.public_project.logs.count())
        assert_equal(res.json['data'][API_LATEST]['attributes']['action'],
                     'tag_removed')
        assert_equal("Jeff Spies",
                     self.public_project.logs.latest().params['tag'])

    def test_project_created(self):
        res = self.app.get(self.public_url)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), self.public_project.logs.count())
        assert_equal(self.public_project.logs.first().action,
                     'project_created')
        assert_equal(self.public_project.logs.first().action,
                     res.json['data'][API_LATEST]['attributes']['action'])

    def test_log_create_on_public_project(self):
        res = self.app.get(self.public_url)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), self.public_project.logs.count())
        assert_datetime_equal(
            parse_date(res.json['data'][API_FIRST]['attributes']['date']),
            self.public_project.logs.first().date)
        assert_equal(res.json['data'][API_FIRST]['attributes']['action'],
                     self.public_project.logs.first().action)

    def test_log_create_on_private_project(self):
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), self.public_project.logs.count())
        assert_datetime_equal(
            parse_date(res.json['data'][API_FIRST]['attributes']['date']),
            self.private_project.logs.first().date)
        assert_equal(res.json['data'][API_FIRST]['attributes']['action'],
                     self.private_project.logs.first().action)

    def test_add_addon(self):
        self.public_project.add_addon('github', auth=self.user_auth)
        assert_equal('addon_added', self.public_project.logs.latest().action)
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), self.public_project.logs.count())
        assert_equal(res.json['data'][API_LATEST]['attributes']['action'],
                     'addon_added')

    def test_project_add_remove_contributor(self):
        self.public_project.add_contributor(self.contrib, auth=self.user_auth)
        assert_equal('contributor_added',
                     self.public_project.logs.latest().action)
        # Disconnect contributor_removed so that we don't check in files
        # We can remove this when StoredFileNode is implemented in osf-models
        with disconnected_from_listeners(contributor_removed):
            self.public_project.remove_contributor(self.contrib,
                                                   auth=self.user_auth)
        assert_equal('contributor_removed',
                     self.public_project.logs.latest().action)
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), self.public_project.logs.count())
        assert_equal(res.json['data'][API_LATEST]['attributes']['action'],
                     'contributor_removed')
        assert_equal(res.json['data'][1]['attributes']['action'],
                     'contributor_added')

    def test_remove_addon(self):
        self.public_project.add_addon('github', auth=self.user_auth)
        assert_equal('addon_added', self.public_project.logs.latest().action)
        old_log_length = len(list(self.public_project.logs.all()))
        self.public_project.delete_addon('github', auth=self.user_auth)
        assert_equal('addon_removed', self.public_project.logs.latest().action)
        assert_equal((self.public_project.logs.count() - 1), old_log_length)
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), self.public_project.logs.count())
        assert_equal(res.json['data'][API_LATEST]['attributes']['action'],
                     'addon_removed')

    def test_add_pointer(self):
        self.public_project.add_pointer(self.pointer,
                                        auth=Auth(self.user),
                                        save=True)
        assert_equal('pointer_created',
                     self.public_project.logs.latest().action)
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), self.public_project.logs.count())
        assert_equal(res.json['data'][API_LATEST]['attributes']['action'],
                     'pointer_created')
Пример #29
0
class TestCallbacks(OsfTestCase):
    def setUp(self):

        super(TestCallbacks, self).setUp()

        self.project = ProjectFactory()
        self.consolidated_auth = Auth(self.project.creator)
        self.non_authenticator = UserFactory()
        self.project.add_contributor(
            contributor=self.non_authenticator,
            auth=self.consolidated_auth,
        )

        self.project.add_addon('bitbucket', auth=self.consolidated_auth)
        self.project.creator.add_addon('bitbucket')
        self.external_account = BitbucketAccountFactory()
        self.project.creator.external_accounts.add(self.external_account)
        self.node_settings = self.project.get_addon('bitbucket')
        self.user_settings = self.project.creator.get_addon('bitbucket')
        self.node_settings.user_settings = self.user_settings
        self.node_settings.user = '******'
        self.node_settings.repo = 'Sheer-Heart-Attack'
        self.node_settings.external_account = self.external_account
        self.node_settings.save()
        self.node_settings.set_auth
        self.user_settings.oauth_grants[self.project._id] = {
            self.external_account._id: []
        }
        self.user_settings.save()

    @mock.patch('addons.bitbucket.api.BitbucketClient.repo')
    def test_before_make_public(self, mock_repo):
        mock_repo.side_effect = NotFoundError

        result = self.node_settings.before_make_public(self.project)
        assert_is(result, None)

    @mock.patch('addons.bitbucket.api.BitbucketClient.repo')
    def test_before_page_load_osf_public_bb_public(self, mock_repo):
        self.project.is_public = True
        self.project.save()
        mock_repo.return_value = {'is_private': False}
        message = self.node_settings.before_page_load(self.project,
                                                      self.project.creator)
        mock_repo.assert_called_with(
            user=self.node_settings.user,
            repo=self.node_settings.repo,
        )
        assert_false(message)

    @mock.patch('addons.bitbucket.api.BitbucketClient.repo')
    def test_before_page_load_osf_public_bb_private(self, mock_repo):
        self.project.is_public = True
        self.project.save()
        mock_repo.return_value = {'is_private': True}
        message = self.node_settings.before_page_load(self.project,
                                                      self.project.creator)
        mock_repo.assert_called_with(
            user=self.node_settings.user,
            repo=self.node_settings.repo,
        )
        assert_true(message)
        assert_in(
            'Users can view the contents of this private Bitbucket repository through this public project.',
            message[0])

    @mock.patch('addons.bitbucket.api.BitbucketClient.repo')
    def test_before_page_load_repo_deleted(self, mock_repo):
        self.project.is_public = True
        self.project.save()
        mock_repo.return_value = None
        message = self.node_settings.before_page_load(self.project,
                                                      self.project.creator)
        mock_repo.assert_called_with(
            user=self.node_settings.user,
            repo=self.node_settings.repo,
        )
        assert_true(message)
        assert_in('has been deleted.', message[0])

    @mock.patch('addons.bitbucket.api.BitbucketClient.repo')
    def test_before_page_load_osf_private_bb_public(self, mock_repo):
        mock_repo.return_value = {'is_private': False}
        message = self.node_settings.before_page_load(self.project,
                                                      self.project.creator)
        mock_repo.assert_called_with(
            user=self.node_settings.user,
            repo=self.node_settings.repo,
        )
        assert_true(message)
        assert_in(
            'The files in this Bitbucket repo can be viewed on Bitbucket',
            message[0])

    @mock.patch('addons.bitbucket.api.BitbucketClient.repo')
    def test_before_page_load_osf_private_bb_private(self, mock_repo):
        mock_repo.return_value = {'is_private': True}
        message = self.node_settings.before_page_load(self.project,
                                                      self.project.creator)
        mock_repo.assert_called_with(
            user=self.node_settings.user,
            repo=self.node_settings.repo,
        )
        assert_false(message)

    def test_before_page_load_not_contributor(self):
        message = self.node_settings.before_page_load(self.project,
                                                      UserFactory())
        assert_false(message)

    def test_before_page_load_not_logged_in(self):
        message = self.node_settings.before_page_load(self.project, None)
        assert_false(message)

    def test_before_remove_contributor_authenticator(self):
        message = self.node_settings.before_remove_contributor(
            self.project, self.project.creator)
        assert_true(message)

    def test_before_remove_contributor_not_authenticator(self):
        message = self.node_settings.before_remove_contributor(
            self.project, self.non_authenticator)
        assert_false(message)

    def test_after_remove_contributor_authenticator_self(self):
        message = self.node_settings.after_remove_contributor(
            self.project, self.project.creator, self.consolidated_auth)
        assert_equal(self.node_settings.user_settings, None)
        assert_true(message)
        assert_not_in('You can re-authenticate', message)

    def test_after_remove_contributor_authenticator_not_self(self):
        auth = Auth(user=self.non_authenticator)
        message = self.node_settings.after_remove_contributor(
            self.project, self.project.creator, auth)
        assert_equal(self.node_settings.user_settings, None)
        assert_true(message)
        assert_in('You can re-authenticate', message)

    def test_after_remove_contributor_not_authenticator(self):
        self.node_settings.after_remove_contributor(self.project,
                                                    self.non_authenticator,
                                                    self.consolidated_auth)
        assert_not_equal(
            self.node_settings.user_settings,
            None,
        )

    def test_after_fork_authenticator(self):
        fork = ProjectFactory()
        clone = self.node_settings.after_fork(
            self.project,
            fork,
            self.project.creator,
        )
        assert_equal(
            self.node_settings.user_settings,
            clone.user_settings,
        )

    def test_after_fork_not_authenticator(self):
        fork = ProjectFactory()
        clone = self.node_settings.after_fork(
            self.project,
            fork,
            self.non_authenticator,
        )
        assert_equal(
            clone.user_settings,
            None,
        )

    def test_after_delete(self):
        self.project.remove_node(Auth(user=self.project.creator))
        # Ensure that changes to node settings have been saved
        self.node_settings.reload()
        assert_true(self.node_settings.user_settings is None)

    @mock.patch('website.archiver.tasks.archive')
    def test_does_not_get_copied_to_registrations(self, mock_archive):
        registration = self.project.register_node(
            schema=get_default_metaschema(),
            auth=Auth(user=self.project.creator),
            data='hodor',
        )
        assert_false(registration.has_addon('bitbucket'))
Пример #30
0
class TestGitLabSettings(OsfTestCase):

    def setUp(self):

        super(TestGitLabSettings, self).setUp()
        self.gitlab = create_mock_gitlab(user='******', private=False)
        self.project = ProjectFactory()
        self.auth = self.project.creator.auth
        self.consolidated_auth = Auth(user=self.project.creator)

        self.project.add_addon('gitlab', auth=self.consolidated_auth)
        self.project.creator.add_addon('gitlab')
        self.node_settings = self.project.get_addon('gitlab')
        self.user_settings = self.project.creator.get_addon('gitlab')
        self.node_settings.user_settings = self.user_settings
        self.node_settings.user = '******'
        self.node_settings.repo = 'Sheer-Heart-Attack'
        self.node_settings.repo_id = 'sheer-heart-attack'
        self.node_settings.save()

    @mock.patch('addons.gitlab.models.NodeSettings.add_hook')
    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_link_repo(self, mock_repo, mock_add_hook):
        gitlab_mock = self.gitlab
        mock_repo.return_value = gitlab_mock.repo.return_value

        url = self.project.api_url + 'gitlab/settings/'
        self.app.post_json(
            url,
            {
                'gitlab_user': '******',
                'gitlab_repo': 'night at the opera',
                'gitlab_repo_id': 'abc',
            },
            auth=self.auth
        ).maybe_follow()

        self.project.reload()
        self.node_settings.reload()

        assert_equal(self.node_settings.user, 'queen')
        assert_equal(self.node_settings.repo, 'night at the opera')
        assert_equal(self.project.logs.latest().action, 'gitlab_repo_linked')
        mock_add_hook.assert_called_once_with(save=False)

    @mock.patch('addons.gitlab.models.NodeSettings.add_hook')
    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_link_repo_no_change(self, mock_repo, mock_add_hook):
        gitlab_mock = self.gitlab
        mock_repo.return_value = gitlab_mock.repo.return_value

        log_count = self.project.logs.count()

        url = self.project.api_url + 'gitlab/settings/'
        self.app.post_json(
            url,
            {
                'gitlab_user': self.node_settings.user,
                'gitlab_repo': self.node_settings.repo,
                'gitlab_repo_id': self.node_settings.repo_id,
            },
            auth=self.auth
        ).maybe_follow()

        self.project.reload()
        self.node_settings.reload()

        assert_equal(self.project.logs.count(), log_count)
        assert_false(mock_add_hook.called)

    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_link_repo_non_existent(self, mock_repo):

        mock_repo.return_value = None

        url = self.project.api_url + 'gitlab/settings/'
        res = self.app.post_json(
            url,
            {
                'gitlab_user': '******',
                'gitlab_repo': 'night at the opera',
            },
            auth=self.auth,
            expect_errors=True
        ).maybe_follow()

        assert_equal(res.status_code, 400)

    @mock.patch('addons.gitlab.api.GitLabClient.branches')
    def test_link_repo_registration(self, mock_branches):

        mock_branches.return_value = [
            Branch.from_json(dumps({
                'name': 'master',
                'commit': {
                    'sha': '6dcb09b5b57875f334f61aebed695e2e4193db5e',
                    'url': 'https://api.gitlab.com/repos/octocat/Hello-World/commits/c5b97d5ae6c19d5c5df71a34c7fbeeda2479ccbc',
                }
            })),
            Branch.from_json(dumps({
                'name': 'develop',
                'commit': {
                    'sha': '6dcb09b5b57875asdasedawedawedwedaewdwdass',
                    'url': 'https://api.gitlab.com/repos/octocat/Hello-World/commits/cdcb09b5b57875asdasedawedawedwedaewdwdass',
                }
            }))
        ]

        registration = self.project.register_node(
            schema=get_default_metaschema(),
            auth=self.consolidated_auth,
            data=''
        )

        url = registration.api_url + 'gitlab/settings/'
        res = self.app.post_json(
            url,
            {
                'gitlab_user': '******',
                'gitlab_repo': 'night at the opera',
            },
            auth=self.auth,
            expect_errors=True
        ).maybe_follow()

        assert_equal(res.status_code, 400)

    @mock.patch('addons.gitlab.models.NodeSettings.delete_hook')
    def test_deauthorize(self, mock_delete_hook):

        url = self.project.api_url + 'gitlab/user_auth/'

        self.app.delete(url, auth=self.auth).maybe_follow()

        self.project.reload()
        self.node_settings.reload()
        assert_equal(self.node_settings.user, None)
        assert_equal(self.node_settings.repo, None)
        assert_equal(self.node_settings.user_settings, None)

        assert_equal(self.project.logs.latest().action, 'gitlab_node_deauthorized')
Пример #31
0
class TestGitLabSettings(OsfTestCase):
    def setUp(self):

        super(TestGitLabSettings, self).setUp()
        self.gitlab = create_mock_gitlab(user='******', private=False)
        self.project = ProjectFactory()
        self.auth = self.project.creator.auth
        self.consolidated_auth = Auth(user=self.project.creator)

        self.project.add_addon('gitlab', auth=self.consolidated_auth)
        self.project.creator.add_addon('gitlab')
        self.node_settings = self.project.get_addon('gitlab')
        self.user_settings = self.project.creator.get_addon('gitlab')
        self.node_settings.user_settings = self.user_settings
        self.node_settings.user = '******'
        self.node_settings.repo = 'Sheer-Heart-Attack'
        self.node_settings.repo_id = 'sheer-heart-attack'
        self.node_settings.save()

    @mock.patch('addons.gitlab.models.NodeSettings.add_hook')
    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_link_repo(self, mock_repo, mock_add_hook):
        gitlab_mock = self.gitlab
        mock_repo.return_value = gitlab_mock.repo.return_value

        url = self.project.api_url + 'gitlab/settings/'
        self.app.post_json(url, {
            'gitlab_user': '******',
            'gitlab_repo': 'night at the opera',
            'gitlab_repo_id': 'abc',
        },
                           auth=self.auth).maybe_follow()

        self.project.reload()
        self.node_settings.reload()

        assert_equal(self.node_settings.user, 'queen')
        assert_equal(self.node_settings.repo, 'night at the opera')
        assert_equal(self.project.logs.latest().action, 'gitlab_repo_linked')
        mock_add_hook.assert_called_once_with(save=False)

    @mock.patch('addons.gitlab.models.NodeSettings.add_hook')
    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_link_repo_no_change(self, mock_repo, mock_add_hook):
        gitlab_mock = self.gitlab
        mock_repo.return_value = gitlab_mock.repo.return_value

        log_count = self.project.logs.count()

        url = self.project.api_url + 'gitlab/settings/'
        self.app.post_json(url, {
            'gitlab_user': self.node_settings.user,
            'gitlab_repo': self.node_settings.repo,
            'gitlab_repo_id': self.node_settings.repo_id,
        },
                           auth=self.auth).maybe_follow()

        self.project.reload()
        self.node_settings.reload()

        assert_equal(self.project.logs.count(), log_count)
        assert_false(mock_add_hook.called)

    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_link_repo_non_existent(self, mock_repo):

        mock_repo.return_value = None

        url = self.project.api_url + 'gitlab/settings/'
        res = self.app.post_json(url, {
            'gitlab_user': '******',
            'gitlab_repo': 'night at the opera',
        },
                                 auth=self.auth,
                                 expect_errors=True).maybe_follow()

        assert_equal(res.status_code, 400)

    @mock.patch('addons.gitlab.api.GitLabClient.branches')
    def test_link_repo_registration(self, mock_branches):

        mock_branches.return_value = [
            Branch.from_json(
                dumps({
                    'name': 'master',
                    'commit': {
                        'sha':
                        '6dcb09b5b57875f334f61aebed695e2e4193db5e',
                        'url':
                        'https://api.gitlab.com/repos/octocat/Hello-World/commits/c5b97d5ae6c19d5c5df71a34c7fbeeda2479ccbc',
                    }
                })),
            Branch.from_json(
                dumps({
                    'name': 'develop',
                    'commit': {
                        'sha':
                        '6dcb09b5b57875asdasedawedawedwedaewdwdass',
                        'url':
                        'https://api.gitlab.com/repos/octocat/Hello-World/commits/cdcb09b5b57875asdasedawedawedwedaewdwdass',
                    }
                }))
        ]

        registration = self.project.register_node(
            schema=get_default_metaschema(),
            auth=self.consolidated_auth,
            data='')

        url = registration.api_url + 'gitlab/settings/'
        res = self.app.post_json(url, {
            'gitlab_user': '******',
            'gitlab_repo': 'night at the opera',
        },
                                 auth=self.auth,
                                 expect_errors=True).maybe_follow()

        assert_equal(res.status_code, 400)

    @mock.patch('addons.gitlab.models.NodeSettings.delete_hook')
    def test_deauthorize(self, mock_delete_hook):

        url = self.project.api_url + 'gitlab/user_auth/'

        self.app.delete(url, auth=self.auth).maybe_follow()

        self.project.reload()
        self.node_settings.reload()
        assert_equal(self.node_settings.user, None)
        assert_equal(self.node_settings.repo, None)
        assert_equal(self.node_settings.user_settings, None)

        assert_equal(self.project.logs.latest().action,
                     'gitlab_node_deauthorized')
Пример #32
0
class TestCreateContainer(SwiftAddonTestCase, OsfTestCase):
    def setUp(self):

        super(TestCreateContainer, 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('swift', auth=self.consolidated_auth)
        self.project.creator.add_addon('swift')

        self.user_settings = self.user.get_addon('swift')
        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('swift')
        self.node_settings.container = 'Sheer-Heart-Attack'
        self.node_settings.user_settings = self.project.creator.get_addon(
            'swift')

        self.node_settings.save()

    def test_bad_names(self):
        assert_false(validate_container_name(''))
        assert_false(validate_container_name('a' * 257))
        assert_false(validate_container_name('a/b'))
        assert_false(validate_container_name('a/'))
        assert_false(validate_container_name('/a'))

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

    @mock.patch('addons.swift.views.utils.create_container')
    @mock.patch('addons.swift.views.utils.get_container_names')
    def test_create_container_pass(self, mock_names, mock_make):
        mock_make.return_value = True
        mock_names.return_value = ['butintheend', 'it', 'doesntevenmatter']
        url = self.project.api_url_for('swift_create_container')
        ret = self.app.post_json(url, {'container_name': 'doesntevenmatter'},
                                 auth=self.user.auth)

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

    @mock.patch('addons.swift.views.utils.create_container')
    def test_create_container_fail(self, mock_make):
        error = swift_exceptions.ClientException(
            'This should work',
            http_status=418,
            http_reason='because Im a test')
        mock_make.side_effect = error

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

        assert_equals(
            ret.body,
            '{"message": "This should work", "title": "Problem creating container \'doesntevenmatter\'"}'
        )
Пример #33
0
class TestNodeFilesListFiltering(ApiTestCase):

    def setUp(self):
        super(TestNodeFilesListFiltering, self).setUp()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        httpretty.enable()
        # Prep HTTP mocks
        prepare_mock_wb_response(
            node=self.project,
            provider='github',
            files=[
                {'name': 'abc', 'path': '/abc/', 'materialized': '/abc/', 'kind': 'folder'},
                {'name': 'xyz', 'path': '/xyz', 'materialized': '/xyz', 'kind': 'file'},
            ]
        )

    def tearDown(self):
        super(TestNodeFilesListFiltering, self).tearDown()
        httpretty.disable()
        httpretty.reset()

    def add_github(self):
        user_auth = Auth(self.user)
        self.project.add_addon('github', auth=user_auth)
        addon = self.project.get_addon('github')
        addon.repo = 'something'
        addon.user = '******'
        oauth_settings = GitHubAccountFactory()
        oauth_settings.save()
        self.user.add_addon('github')
        self.user.external_accounts.add(oauth_settings)
        self.user.save()
        addon.user_settings = self.user.get_addon('github')
        addon.external_account = oauth_settings
        addon.save()
        self.project.save()
        addon.user_settings.oauth_grants[self.project._id] = {oauth_settings._id: []}
        addon.user_settings.save()

    def test_node_files_are_filterable_by_name(self):
        url = '/{}nodes/{}/files/github/?filter[name]=xyz'.format(API_BASE, self.project._id)
        self.add_github()
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 1)  # filters out 'abc'
        assert_equal(res.json['data'][0]['attributes']['name'], 'xyz')

    def test_node_files_filter_by_name_case_insensitive(self):
        url = '/{}nodes/{}/files/github/?filter[name]=XYZ'.format(API_BASE, self.project._id)
        self.add_github()
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 1)  # filters out 'abc', but finds 'xyz'
        assert_equal(res.json['data'][0]['attributes']['name'], 'xyz')

    def test_node_files_are_filterable_by_path(self):
        url = '/{}nodes/{}/files/github/?filter[path]=abc'.format(API_BASE, self.project._id)
        self.add_github()
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 1)  # filters out 'xyz'
        assert_equal(res.json['data'][0]['attributes']['name'], 'abc')

    def test_node_files_are_filterable_by_kind(self):
        url = '/{}nodes/{}/files/github/?filter[kind]=folder'.format(API_BASE, self.project._id)
        self.add_github()
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 1)  # filters out 'xyz'
        assert_equal(res.json['data'][0]['attributes']['name'], 'abc')

    def test_node_files_external_provider_can_filter_by_last_touched(self):
        yesterday_stamp = timezone.now() - datetime.timedelta(days=1)
        self.add_github()
        url = '/{}nodes/{}/files/github/?filter[last_touched][gt]={}'.format(API_BASE,
                                                                             self.project._id,
                                                                             yesterday_stamp.isoformat())
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 2)

    def test_node_files_osfstorage_cannot_filter_by_last_touched(self):
        yesterday_stamp = timezone.now() - datetime.timedelta(days=1)
        self.file = api_utils.create_test_file(self.project, self.user)

        url = '/{}nodes/{}/files/osfstorage/?filter[last_touched][gt]={}'.format(API_BASE,
                                                                                 self.project._id,
                                                                                 yesterday_stamp.isoformat())
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)
        assert_equal(len(res.json['errors']), 1)
Пример #34
0
class TestBitbucketViews(OsfTestCase):

    def setUp(self):
        super(TestBitbucketViews, self).setUp()
        self.user = AuthUserFactory()
        self.consolidated_auth = Auth(user=self.user)

        self.project = ProjectFactory(creator=self.user)
        self.non_authenticator = UserFactory()
        self.project.add_contributor(
            contributor=self.non_authenticator,
            auth=self.consolidated_auth,
        )
        self.project.save()

        self.external_account = BitbucketAccountFactory()

        self.project.add_addon('bitbucket', auth=self.consolidated_auth)
        self.project.creator.add_addon('bitbucket')
        self.project.creator.external_accounts.add(self.external_account)
        self.project.creator.save()

        self.bitbucket = create_mock_bitbucket(user='******', private=False)

        self.user_settings = self.project.creator.get_addon('bitbucket')
        self.user_settings.oauth_grants[self.project._id] = {self.external_account._id: []}
        self.user_settings.save()

        self.node_settings = self.project.get_addon('bitbucket')
        self.node_settings.user_settings = self.user_settings
        self.node_settings.external_account = self.external_account
        self.node_settings.user = self.bitbucket.repo.return_value['owner']['username']
        self.node_settings.repo = self.bitbucket.repo.return_value['name']
        self.node_settings.save()

    def _get_sha_for_branch(self, branch=None, mock_branches=None):
        bitbucket_mock = self.bitbucket
        if mock_branches is None:
            mock_branches = bitbucket_mock.branches
        if branch is None:  # Get default branch name
            branch = self.bitbucket.repo_default_branch.return_value
        for each in mock_branches.return_value:
            if each['name'] == branch:
                branch_sha = each['target']['hash']
        return branch_sha

    # Tests for _get_refs
    @mock.patch('addons.bitbucket.api.BitbucketClient.branches')
    @mock.patch('addons.bitbucket.api.BitbucketClient.repo')
    @mock.patch('addons.bitbucket.api.BitbucketClient.repo_default_branch')
    @mock.patch('addons.bitbucket.models.NodeSettings.external_account')
    def test_get_refs_defaults(self, mock_account, mock_default_branch, mock_repo, mock_branches):
        bitbucket_mock = self.bitbucket
        mock_account.return_value = mock.Mock()
        mock_default_branch.return_value = bitbucket_mock.repo_default_branch.return_value
        mock_repo.return_value = bitbucket_mock.repo.return_value
        mock_branches.return_value = bitbucket_mock.branches.return_value

        branch, sha, branches = utils.get_refs(self.node_settings)
        assert_equal(
            branch,
            bitbucket_mock.repo_default_branch.return_value
        )
        assert_equal(sha, self._get_sha_for_branch(branch=None))  # Get refs for default branch

        expected_branches = [
            {'name': x['name'], 'sha': x['target']['hash']}
            for x in bitbucket_mock.branches.return_value
        ]
        assert_equal(branches, expected_branches)

    @mock.patch('addons.bitbucket.api.BitbucketClient.branches')
    @mock.patch('addons.bitbucket.api.BitbucketClient.repo')
    @mock.patch('addons.bitbucket.api.BitbucketClient.repo_default_branch')
    @mock.patch('addons.bitbucket.models.NodeSettings.external_account')
    def test_get_refs_branch(self, mock_account, mock_default_branch, mock_repo, mock_branches):
        bitbucket_mock = self.bitbucket
        mock_account.return_value = mock.Mock()
        mock_default_branch.return_value = bitbucket_mock.repo_default_branch.return_value
        mock_repo.return_value = bitbucket_mock.repo.return_value
        mock_branches.return_value = bitbucket_mock.branches.return_value

        branch, sha, branches = utils.get_refs(self.node_settings, 'master')
        assert_equal(branch, 'master')
        branch_sha = self._get_sha_for_branch('master')
        assert_equal(sha, branch_sha)

        expected_branches = [
            {'name': x['name'], 'sha': x['target']['hash']}
            for x in bitbucket_mock.branches.return_value
        ]
        assert_equal(branches, expected_branches)

    def test_before_fork(self):
        url = self.project.api_url + 'fork/before/'
        res = self.app.get(url, auth=self.user.auth).maybe_follow()
        assert_equal(len(res.json['prompts']), 1)

    def test_before_register(self):
        url = self.project.api_url + 'beforeregister/'
        res = self.app.get(url, auth=self.user.auth).maybe_follow()
        assert_true('Bitbucket' in res.json['prompts'][1])

    @mock.patch('addons.bitbucket.models.NodeSettings.external_account')
    def test_get_refs_sha_no_branch(self, mock_account):
        with assert_raises(HTTPError):
            utils.get_refs(self.node_settings, sha='12345')

    def check_hook_urls(self, urls, node, path, sha):
        url = node.web_url_for('addon_view_or_download_file', path=path, provider='bitbucket')
        expected_urls = {
            'view': '{0}?ref={1}'.format(url, sha),
            'download': '{0}?action=download&ref={1}'.format(url, sha)
        }

        assert_equal(urls['view'], expected_urls['view'])
        assert_equal(urls['download'], expected_urls['download'])
Пример #35
0
class TestGitLabViews(OsfTestCase):
    def setUp(self):
        super(TestGitLabViews, self).setUp()
        self.user = AuthUserFactory()
        self.consolidated_auth = Auth(user=self.user)

        self.project = ProjectFactory(creator=self.user)
        self.non_authenticator = UserFactory()
        self.project.add_contributor(
            contributor=self.non_authenticator,
            auth=self.consolidated_auth,
        )
        self.project.save()
        self.project.add_addon('gitlab', auth=self.consolidated_auth)
        self.project.creator.add_addon('gitlab')
        self.project.creator.external_accounts.add(GitLabAccountFactory())
        self.project.creator.save()

        self.gitlab = create_mock_gitlab(user='******', private=False)

        self.node_settings = self.project.get_addon('gitlab')
        self.node_settings.user_settings = self.project.creator.get_addon(
            'gitlab')
        # Set the node addon settings to correspond to the values of the mock repo
        self.node_settings.user = '******'
        self.node_settings.repo = 'mock-repo'
        self.node_settings.repo_id = 1748448
        self.node_settings.save()

    def _get_sha_for_branch(self, branch=None, mock_branches=None):
        gitlab_mock = self.gitlab
        if mock_branches is None:
            mock_branches = gitlab_mock.branches
        if branch is None:  # Get default branch name
            branch = self.gitlab.repo.default_branch
        for each in mock_branches:
            if each.name == branch:
                branch_sha = each.commit['id']
        return branch_sha

    # Tests for _get_refs
    @mock.patch('addons.gitlab.api.GitLabClient.branches')
    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_get_refs_defaults(self, mock_repo, mock_branches):
        gitlab_mock = self.gitlab
        mock_repo.return_value = gitlab_mock.repo
        mock_branches.return_value = gitlab_mock.branches.return_value
        branch, sha, branches = utils.get_refs(self.node_settings)
        assert_equal(branch, gitlab_mock.repo.default_branch)
        assert_equal(sha,
                     branches[0].commit['id'])  # Get refs for default branch
        assert_equal(branches, gitlab_mock.branches.return_value)

    @mock.patch('addons.gitlab.api.GitLabClient.branches')
    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_get_refs_branch(self, mock_repo, mock_branches):
        gitlab_mock = self.gitlab
        mock_repo.return_value = gitlab_mock.repo.return_value
        mock_branches.return_value = gitlab_mock.branches.return_value
        branch, sha, branches = utils.get_refs(self.node_settings, 'master')
        assert_equal(branch, 'master')
        assert_equal(sha, branches[0].commit['id'])
        assert_equal(branches, gitlab_mock.branches.return_value)

    def test_before_fork(self):
        url = self.project.api_url + 'fork/before/'
        res = self.app.get(url, auth=self.user.auth).maybe_follow()
        assert_equal(len(res.json['prompts']), 1)

    @mock.patch('addons.gitlab.models.UserSettings.has_auth')
    def test_before_register(self, mock_has_auth):
        mock_has_auth.return_value = True
        url = self.project.api_url + 'beforeregister/'
        res = self.app.get(url, auth=self.user.auth).maybe_follow()
        assert_true('GitLab' in res.json['prompts'][1])

    def test_get_refs_sha_no_branch(self):
        with assert_raises(HTTPError):
            utils.get_refs(self.node_settings, sha='12345')

    # Tests for _check_permissions
    # make a user with no authorization; make sure check_permissions returns false
    def test_permissions_no_auth(self):
        gitlab_mock = self.gitlab
        # project is set to private right now
        connection = gitlab_mock
        non_authenticated_user = UserFactory()
        non_authenticated_auth = Auth(user=non_authenticated_user)
        branch = 'master'
        assert_false(
            check_permissions(self.node_settings, non_authenticated_auth,
                              connection, branch))

    # make a repository that doesn't allow push access for this user;
    # make sure check_permissions returns false
    @mock.patch('addons.gitlab.models.UserSettings.has_auth')
    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_permissions_no_access(self, mock_repo, mock_has_auth):
        gitlab_mock = self.gitlab
        mock_has_auth.return_value = True
        connection = gitlab_mock
        branch = 'master'
        mock_repository = mock.Mock(
            **{
                'user': '******',
                'repo': 'mock-repo',
                'permissions': {
                    'project_access': {
                        'access_level': 20,
                        'notification_level': 3
                    }
                },
            })
        mock_repo.attributes.return_value = mock_repository
        assert_false(
            check_permissions(self.node_settings,
                              self.consolidated_auth,
                              connection,
                              branch,
                              repo=mock_repository))

    # make a branch with a different commit than the commit being passed into check_permissions
    @mock.patch('addons.gitlab.models.UserSettings.has_auth')
    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_permissions_not_head(self, mock_repo, mock_has_auth):
        gitlab_mock = self.gitlab
        mock_has_auth.return_value = True
        connection = gitlab_mock
        mock_branch = mock.Mock(**{'commit': {'id': '67890'}})
        connection.branches.return_value = mock_branch
        sha = '12345'
        assert_false(
            check_permissions(self.node_settings,
                              self.consolidated_auth,
                              connection,
                              mock_branch,
                              sha=sha))

    # make sure permissions are not granted for editing a registration
    @mock.patch('addons.gitlab.models.UserSettings.has_auth')
    def test_permissions(self, mock_has_auth):
        gitlab_mock = self.gitlab
        mock_has_auth.return_value = True
        connection = gitlab_mock
        with mock.patch('osf.models.node.AbstractNode.is_registration',
                        new_callable=mock.PropertyMock) as mock_is_reg:
            mock_is_reg.return_value = True
            assert_false(
                check_permissions(self.node_settings, self.consolidated_auth,
                                  connection, 'master'))

    def check_hook_urls(self, urls, node, path, sha):
        url = node.web_url_for('addon_view_or_download_file',
                               path=path,
                               provider='gitlab')
        expected_urls = {
            'view': '{0}?branch={1}'.format(url, sha),
            'download': '{0}?action=download&branch={1}'.format(url, sha)
        }

        assert_equal(urls['view'], expected_urls['view'])
        assert_equal(urls['download'], expected_urls['download'])

    @mock.patch('addons.gitlab.views.verify_hook_signature')
    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_hook_callback_add_file_not_thro_osf(self, mock_repo, mock_verify):
        gitlab_mock = self.gitlab
        gitlab_mock.repo = mock_repo
        url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id)
        timestamp = str(datetime.datetime.utcnow())
        self.app.post_json(
            url,
            {
                'test':
                True,
                'commits': [{
                    'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                    'distinct': True,
                    'message': 'foo',
                    'timestamp': timestamp,
                    'url':
                    'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                    'author': {
                        'name': 'Illidan',
                        'email': '*****@*****.**'
                    },
                    'committer': {
                        'name': 'Testor',
                        'email': '*****@*****.**',
                        'username': '******'
                    },
                    'added': ['PRJWN3TV'],
                    'removed': [],
                    'modified': [],
                }]
            },
            content_type='application/json',
        ).maybe_follow()
        self.project.reload()
        assert_equal(self.project.logs.latest().action, 'gitlab_file_added')
        urls = self.project.logs.latest().params['urls']
        self.check_hook_urls(
            urls,
            self.project,
            path='PRJWN3TV',
            sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
        )

    @mock.patch('addons.gitlab.views.verify_hook_signature')
    def test_hook_callback_modify_file_not_thro_osf(self, mock_verify):
        url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id)
        timestamp = str(datetime.datetime.utcnow())
        self.app.post_json(url, {
            'test':
            True,
            'commits': [{
                'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                'distinct': True,
                'message': ' foo',
                'timestamp': timestamp,
                'url':
                'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                'author': {
                    'name': 'Illidan',
                    'email': '*****@*****.**'
                },
                'committer': {
                    'name': 'Testor',
                    'email': '*****@*****.**',
                    'username': '******'
                },
                'added': [],
                'removed': [],
                'modified': ['PRJWN3TV']
            }]
        },
                           content_type='application/json').maybe_follow()
        self.project.reload()
        assert_equal(self.project.logs.latest().action, 'gitlab_file_updated')
        urls = self.project.logs.latest().params['urls']
        self.check_hook_urls(
            urls,
            self.project,
            path='PRJWN3TV',
            sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
        )

    @mock.patch('addons.gitlab.views.verify_hook_signature')
    def test_hook_callback_remove_file_not_thro_osf(self, mock_verify):
        url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id)
        timestamp = str(datetime.datetime.utcnow())
        self.app.post_json(url, {
            'test':
            True,
            'commits': [{
                'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                'distinct': True,
                'message': 'foo',
                'timestamp': timestamp,
                'url':
                'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                'author': {
                    'name': 'Illidan',
                    'email': '*****@*****.**'
                },
                'committer': {
                    'name': 'Testor',
                    'email': '*****@*****.**',
                    'username': '******'
                },
                'added': [],
                'removed': ['PRJWN3TV'],
                'modified': []
            }]
        },
                           content_type='application/json').maybe_follow()
        self.project.reload()
        assert_equal(self.project.logs.latest().action, 'gitlab_file_removed')
        urls = self.project.logs.latest().params['urls']
        assert_equal(urls, {})

    @mock.patch('addons.gitlab.views.verify_hook_signature')
    def test_hook_callback_add_file_thro_osf(self, mock_verify):
        url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id)
        self.app.post_json(url, {
            'test':
            True,
            'commits': [{
                'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                'distinct': True,
                'message': 'Added via the Open Science Framework',
                'timestamp': '2014-01-08T14:15:51-08:00',
                'url':
                'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                'author': {
                    'name': 'Illidan',
                    'email': '*****@*****.**'
                },
                'committer': {
                    'name': 'Testor',
                    'email': '*****@*****.**',
                    'username': '******'
                },
                'added': ['PRJWN3TV'],
                'removed': [],
                'modified': []
            }]
        },
                           content_type='application/json').maybe_follow()
        self.project.reload()
        assert_not_equal(self.project.logs.latest().action,
                         'gitlab_file_added')

    @mock.patch('addons.gitlab.views.verify_hook_signature')
    def test_hook_callback_modify_file_thro_osf(self, mock_verify):
        url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id)
        self.app.post_json(url, {
            'test':
            True,
            'commits': [{
                'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                'distinct': True,
                'message': 'Updated via the Open Science Framework',
                'timestamp': '2014-01-08T14:15:51-08:00',
                'url':
                'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                'author': {
                    'name': 'Illidan',
                    'email': '*****@*****.**'
                },
                'committer': {
                    'name': 'Testor',
                    'email': '*****@*****.**',
                    'username': '******'
                },
                'added': [],
                'removed': [],
                'modified': ['PRJWN3TV']
            }]
        },
                           content_type='application/json').maybe_follow()
        self.project.reload()
        assert_not_equal(self.project.logs.latest().action,
                         'gitlab_file_updated')

    @mock.patch('addons.gitlab.views.verify_hook_signature')
    def test_hook_callback_remove_file_thro_osf(self, mock_verify):
        url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id)
        self.app.post_json(url, {
            'test':
            True,
            'commits': [{
                'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                'distinct': True,
                'message': 'Deleted via the Open Science Framework',
                'timestamp': '2014-01-08T14:15:51-08:00',
                'url':
                'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                'author': {
                    'name': 'Illidan',
                    'email': '*****@*****.**'
                },
                'committer': {
                    'name': 'Testor',
                    'email': '*****@*****.**',
                    'username': '******'
                },
                'added': [],
                'removed': ['PRJWN3TV'],
                'modified': []
            }]
        },
                           content_type='application/json').maybe_follow()
        self.project.reload()
        assert_not_equal(self.project.logs.latest().action,
                         'gitlab_file_removed')
Пример #36
0
class TestNodeFilesListPagination(ApiTestCase):
    def setUp(self):
        super(TestNodeFilesListPagination, self).setUp()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        httpretty.enable()

    def tearDown(self):
        super(TestNodeFilesListPagination, self).tearDown()
        httpretty.disable()
        httpretty.reset()

    def add_github(self):
        user_auth = Auth(self.user)
        self.project.add_addon('github', auth=user_auth)
        addon = self.project.get_addon('github')
        addon.repo = 'something'
        addon.user = '******'
        oauth_settings = GitHubAccountFactory()
        oauth_settings.save()
        self.user.add_addon('github')
        self.user.external_accounts.add(oauth_settings)
        self.user.save()
        addon.user_settings = self.user.get_addon('github')
        addon.external_account = oauth_settings
        addon.save()
        self.project.save()
        addon.user_settings.oauth_grants[self.project._id] = {oauth_settings._id: []}
        addon.user_settings.save()

    def check_file_order(self, resp):
        previous_file_name = 0
        for file in resp.json['data']:
            int_file_name = int(file['attributes']['name'])
            assert int_file_name > previous_file_name, 'Files were not in order'
            previous_file_name = int_file_name

    def test_node_files_are_sorted_correctly(self):
        prepare_mock_wb_response(
            node=self.project,
            provider='github',
            files=[
                {'name': '01', 'path': '/01/', 'materialized': '/01/', 'kind': 'folder'},
                {'name': '02', 'path': '/02', 'materialized': '/02', 'kind': 'file'},
                {'name': '03', 'path': '/03/', 'materialized': '/03/', 'kind': 'folder'},
                {'name': '04', 'path': '/04', 'materialized': '/04', 'kind': 'file'},
                {'name': '05', 'path': '/05/', 'materialized': '/05/', 'kind': 'folder'},
                {'name': '06', 'path': '/06', 'materialized': '/06', 'kind': 'file'},
                {'name': '07', 'path': '/07/', 'materialized': '/07/', 'kind': 'folder'},
                {'name': '08', 'path': '/08', 'materialized': '/08', 'kind': 'file'},
                {'name': '09', 'path': '/09/', 'materialized': '/09/', 'kind': 'folder'},
                {'name': '10', 'path': '/10', 'materialized': '/10', 'kind': 'file'},
                {'name': '11', 'path': '/11/', 'materialized': '/11/', 'kind': 'folder'},
                {'name': '12', 'path': '/12', 'materialized': '/12', 'kind': 'file'},
                {'name': '13', 'path': '/13/', 'materialized': '/13/', 'kind': 'folder'},
                {'name': '14', 'path': '/14', 'materialized': '/14', 'kind': 'file'},
                {'name': '15', 'path': '/15/', 'materialized': '/15/', 'kind': 'folder'},
                {'name': '16', 'path': '/16', 'materialized': '/16', 'kind': 'file'},
                {'name': '17', 'path': '/17/', 'materialized': '/17/', 'kind': 'folder'},
                {'name': '18', 'path': '/18', 'materialized': '/18', 'kind': 'file'},
                {'name': '19', 'path': '/19/', 'materialized': '/19/', 'kind': 'folder'},
                {'name': '20', 'path': '/20', 'materialized': '/20', 'kind': 'file'},
                {'name': '21', 'path': '/21/', 'materialized': '/21/', 'kind': 'folder'},
                {'name': '22', 'path': '/22', 'materialized': '/22', 'kind': 'file'},
                {'name': '23', 'path': '/23/', 'materialized': '/23/', 'kind': 'folder'},
                {'name': '24', 'path': '/24', 'materialized': '/24', 'kind': 'file'},
            ]
        )
        self.add_github()
        url = '/{}nodes/{}/files/github/?page[size]=100'.format(API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth)
        self.check_file_order(res)
Пример #37
0
class TestCreateContainer(AzureBlobStorageAddonTestCase, OsfTestCase):
    def setUp(self):

        super(TestCreateContainer, 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('azureblobstorage', auth=self.consolidated_auth)
        self.project.creator.add_addon('azureblobstorage')

        self.user_settings = self.user.get_addon('azureblobstorage')
        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('azureblobstorage')
        self.node_settings.container = 'Sheer-Heart-Attack'
        self.node_settings.user_settings = self.project.creator.get_addon(
            'azureblobstorage')

        self.node_settings.save()

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

    def test_names(self):
        assert_true(validate_container_name('imagoodname'))
        assert_true(validate_container_name('can-have-dashes'))
        assert_true(validate_container_name('a--------a'))
        assert_true(validate_container_name('a' * 63))

    @mock.patch('addons.azureblobstorage.views.utils.create_container')
    @mock.patch('addons.azureblobstorage.views.utils.get_container_names')
    def test_create_container_pass(self, mock_names, mock_make):
        mock_make.return_value = True
        mock_names.return_value = ['butintheend', 'it', 'doesntevenmatter']
        url = self.project.api_url_for('azureblobstorage_create_container')
        ret = self.app.post_json(url, {'container_name': 'doesntevenmatter'},
                                 auth=self.user.auth)

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

    @mock.patch('addons.azureblobstorage.views.utils.create_container')
    def test_create_container_fail(self, mock_make):
        error = AzureHttpError('because Im a test', 418)
        error.message = 'This should work'
        mock_make.side_effect = error

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

        assert_equals(
            ret.body,
            '{"message": "This should work", "title": "Problem connecting to Azure Blob Storage"}'
        )
Пример #38
0
class TestNodeFilesList(ApiTestCase):

    def setUp(self):
        super(TestNodeFilesList, self).setUp()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        self.private_url = '/{}nodes/{}/files/'.format(API_BASE, self.project._id)

        self.user_two = AuthUserFactory()

        self.public_project = ProjectFactory(creator=self.user, is_public=True)
        self.public_url = '/{}nodes/{}/files/'.format(API_BASE, self.public_project._id)
        httpretty.enable()

    def tearDown(self):
        super(TestNodeFilesList, self).tearDown()
        httpretty.disable()
        httpretty.reset()

    def add_github(self):
        user_auth = Auth(self.user)
        self.project.add_addon('github', auth=user_auth)
        addon = self.project.get_addon('github')
        addon.repo = 'something'
        addon.user = '******'
        oauth_settings = GitHubAccountFactory()
        oauth_settings.save()
        self.user.add_addon('github')
        self.user.external_accounts.add(oauth_settings)
        self.user.save()
        addon.user_settings = self.user.get_addon('github')
        addon.external_account = oauth_settings
        addon.save()
        self.project.save()
        addon.user_settings.oauth_grants[self.project._id] = {oauth_settings._id: []}
        addon.user_settings.save()

    def _prepare_mock_wb_response(self, node=None, **kwargs):
        prepare_mock_wb_response(node=node or self.project, **kwargs)

    def test_returns_public_files_logged_out(self):
        res = self.app.get(self.public_url, expect_errors=True)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data'][0]['attributes']['provider'], 'osfstorage')
        assert_equal(res.content_type, 'application/vnd.api+json')

    def test_returns_public_files_logged_in(self):
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'application/vnd.api+json')
        assert_equal(res.json['data'][0]['attributes']['provider'], 'osfstorage')

    def test_returns_storage_addons_link(self):
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_in('storage_addons', res.json['data'][0]['links'])

    def test_returns_file_data(self):
        fobj = self.project.get_addon('osfstorage').get_root().append_file('NewFile')
        fobj.save()
        res = self.app.get('{}osfstorage/{}'.format(self.private_url, fobj._id), auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_true(isinstance(res.json['data'], dict))
        assert_equal(res.content_type, 'application/vnd.api+json')
        assert_equal(res.json['data']['attributes']['kind'], 'file')
        assert_equal(res.json['data']['attributes']['name'], 'NewFile')

    def test_returns_osfstorage_folder_version_two(self):
        fobj = self.project.get_addon('osfstorage').get_root().append_folder('NewFolder')
        fobj.save()
        res = self.app.get('{}osfstorage/'.format(self.private_url), auth=self.user.auth)
        assert_equal(res.status_code, 200)

    def test_returns_osf_storage_folder_version_two_point_two(self):
        fobj = self.project.get_addon('osfstorage').get_root().append_folder('NewFolder')
        fobj.save()
        res = self.app.get('{}osfstorage/?version=2.2'.format(self.private_url), auth=self.user.auth)
        assert_equal(res.status_code, 200)

    def test_list_returns_folder_data(self):
        fobj = self.project.get_addon('osfstorage').get_root().append_folder('NewFolder')
        fobj.save()
        res = self.app.get('{}osfstorage/'.format(self.private_url, fobj._id), auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 1)
        assert_equal(res.content_type, 'application/vnd.api+json')
        assert_equal(res.json['data'][0]['attributes']['name'], 'NewFolder')

    def test_returns_folder_data(self):
        fobj = self.project.get_addon('osfstorage').get_root().append_folder('NewFolder')
        fobj.save()
        res = self.app.get('{}osfstorage/{}/'.format(self.private_url, fobj._id), auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 0)
        assert_equal(res.content_type, 'application/vnd.api+json')

    def test_returns_private_files_logged_out(self):
        res = self.app.get(self.private_url, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_in('detail', res.json['errors'][0])

    def test_returns_private_files_logged_in_contributor(self):
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'application/vnd.api+json')
        assert_equal(len(res.json['data']), 1)
        assert_equal(res.json['data'][0]['attributes']['provider'], 'osfstorage')

    def test_returns_private_files_logged_in_non_contributor(self):
        res = self.app.get(self.private_url, auth=self.user_two.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_in('detail', res.json['errors'][0])

    def test_returns_addon_folders(self):
        user_auth = Auth(self.user)
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_equal(len(res.json['data']), 1)
        assert_equal(res.json['data'][0]['attributes']['provider'], 'osfstorage')

        self.project.add_addon('github', auth=user_auth)
        addon = self.project.get_addon('github')
        addon.repo = 'something'
        addon.user = '******'
        oauth_settings = GitHubAccountFactory()
        oauth_settings.save()
        self.user.add_addon('github')
        self.user.external_accounts.add(oauth_settings)
        self.user.save()
        addon.user_settings = self.user.get_addon('github')
        addon.external_account = oauth_settings
        addon.save()
        self.project.save()
        addon.user_settings.oauth_grants[self.project._id] = {oauth_settings._id: []}
        addon.user_settings.save()
        res = self.app.get(self.private_url, auth=self.user.auth)
        data = res.json['data']
        providers = [item['attributes']['provider'] for item in data]
        assert_equal(len(data), 2)
        assert_in('github', providers)
        assert_in('osfstorage', providers)

    def test_returns_node_files_list(self):
        self._prepare_mock_wb_response(provider='github', files=[{'name': 'NewFile'}])
        self.add_github()
        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.json['data'][0]['attributes']['name'], 'NewFile')
        assert_equal(res.json['data'][0]['attributes']['provider'], 'github')

    def test_returns_node_file(self):
        self._prepare_mock_wb_response(provider='github', files=[{'name': 'NewFile'}], folder=False, path='/file')
        self.add_github()
        url = '/{}nodes/{}/files/github/file'.format(API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth, headers={
            'COOKIE': 'foo=bar;'  # Webtests doesnt support cookies?
        })
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['attributes']['name'], 'NewFile')
        assert_equal(res.json['data']['attributes']['provider'], 'github')

    def test_notfound_node_file_returns_folder(self):
        self._prepare_mock_wb_response(provider='github', files=[{'name': 'NewFile'}], path='/file')
        url = '/{}nodes/{}/files/github/file'.format(API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True, headers={
            'COOKIE': 'foo=bar;'  # Webtests doesnt support cookies?
        })
        assert_equal(res.status_code, 404)

    def test_notfound_node_folder_returns_file(self):
        self._prepare_mock_wb_response(provider='github', files=[{'name': 'NewFile'}], folder=False, path='/')

        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True, headers={
            'COOKIE': 'foo=bar;'  # Webtests doesnt support cookies?
        })
        assert_equal(res.status_code, 404)

    def test_waterbutler_server_error_returns_503(self):
        self._prepare_mock_wb_response(status_code=500)
        self.add_github()
        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True, headers={
            'COOKIE': 'foo=bar;'  # Webtests doesnt support cookies?
        })
        assert_equal(res.status_code, 503)

    def test_waterbutler_invalid_data_returns_503(self):
        wb_url = waterbutler_api_url_for(self.project._id, provider='github', path='/', meta=True)
        self.add_github()
        httpretty.register_uri(
            httpretty.GET,
            wb_url,
            body=json.dumps({}),
            status=400
        )
        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 503)

    def test_handles_unauthenticated_waterbutler_request(self):
        self._prepare_mock_wb_response(status_code=401)
        self.add_github()
        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_in('detail', res.json['errors'][0])

    def test_handles_notfound_waterbutler_request(self):
        invalid_provider = 'gilkjadsflhub'
        self._prepare_mock_wb_response(status_code=404, provider=invalid_provider)
        url = '/{}nodes/{}/files/{}/'.format(API_BASE, self.project._id, invalid_provider)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 404)
        assert_in('detail', res.json['errors'][0])

    def test_handles_request_to_provider_not_configured_on_project(self):
        provider = 'box'
        url = '/{}nodes/{}/files/{}/'.format(API_BASE, self.project._id, provider)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_false(self.project.get_addon(provider))
        assert_equal(res.status_code, 404)
        assert_equal(res.json['errors'][0]['detail'], 'The {} provider is not configured for this project.'.format(provider))

    def test_handles_bad_waterbutler_request(self):
        wb_url = waterbutler_api_url_for(self.project._id, provider='github', path='/', meta=True)
        httpretty.register_uri(
            httpretty.GET,
            wb_url,
            body=json.dumps({}),
            status=418
        )
        self.add_github()
        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 503)
        assert_in('detail', res.json['errors'][0])

    def test_files_list_contains_relationships_object(self):
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert 'relationships' in res.json['data'][0]
Пример #39
0
class TestViewUtils(OsfTestCase):

    def setUp(self):
        super(TestViewUtils, self).setUp()
        self.user = AuthUserFactory()
        self.auth_obj = Auth(user=self.user)
        self.node = ProjectFactory(creator=self.user)
        self.session = Session(data={'auth_user_id': self.user._id})
        self.session.save()
        self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id)
        self.configure_addon()
        self.JWE_KEY = jwe.kdf(settings.WATERBUTLER_JWE_SECRET.encode('utf-8'), settings.WATERBUTLER_JWE_SALT.encode('utf-8'))

    def configure_addon(self):
        self.user.add_addon('github')
        self.user_addon = self.user.get_addon('github')
        self.oauth_settings = GitHubAccountFactory(display_name='john')
        self.oauth_settings.save()
        self.user.external_accounts.add(self.oauth_settings)
        self.user.save()
        self.node.add_addon('github', self.auth_obj)
        self.node_addon = self.node.get_addon('github')
        self.node_addon.user = '******'
        self.node_addon.repo = 'youre-my-best-friend'
        self.node_addon.user_settings = self.user_addon
        self.node_addon.external_account = self.oauth_settings
        self.node_addon.save()
        self.user_addon.oauth_grants[self.node._id] = {self.oauth_settings._id: []}
        self.user_addon.save()

    def test_serialize_addons(self):
        addon_dicts = serialize_addons(self.node, self.auth_obj)

        enabled_addons = [addon for addon in addon_dicts if addon['enabled']]
        assert len(enabled_addons) == 2
        assert enabled_addons[0]['short_name'] == 'github'
        assert enabled_addons[1]['short_name'] == 'osfstorage'

        default_addons = [addon for addon in addon_dicts if addon['default']]
        assert len(default_addons) == 1
        assert default_addons[0]['short_name'] == 'osfstorage'

    def test_include_template_json(self):
        """ Some addons (github, gitlab) need more specialized template infomation so we want to
        ensure we get those extra variables that when the addon is enabled.
        """
        addon_dicts = serialize_addons(self.node, self.auth_obj)

        enabled_addons = [addon for addon in addon_dicts if addon['enabled']]
        assert len(enabled_addons) == 2
        assert enabled_addons[1]['short_name'] == 'osfstorage'
        assert enabled_addons[0]['short_name'] == 'github'
        assert 'node_has_auth' in enabled_addons[0]
        assert 'valid_credentials' in enabled_addons[0]

    def test_collect_node_config_js(self):

        addon_dicts = serialize_addons(self.node, self.auth_obj)

        asset_paths = collect_node_config_js(addon_dicts)

        # Default addons should be in addon dicts, but they have no js assets because you can't
        # connect/disconnect from them, think osfstorage, there's no node-cfg for that.
        default_addons = [addon['short_name'] for addon in addon_dicts if addon['default']]
        assert not any('/{}/'.format(addon) in asset_paths for addon in default_addons)
Пример #40
0
class TestAddonAuth(OsfTestCase):

    def setUp(self):
        super(TestAddonAuth, self).setUp()
        self.user = AuthUserFactory()
        self.auth_obj = Auth(user=self.user)
        self.node = ProjectFactory(creator=self.user)
        self.session = Session(data={'auth_user_id': self.user._id})
        self.session.save()
        self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id)
        self.configure_addon()
        self.JWE_KEY = jwe.kdf(settings.WATERBUTLER_JWE_SECRET.encode('utf-8'), settings.WATERBUTLER_JWE_SALT.encode('utf-8'))

    def configure_addon(self):
        self.user.add_addon('github')
        self.user_addon = self.user.get_addon('github')
        self.oauth_settings = GitHubAccountFactory(display_name='john')
        self.oauth_settings.save()
        self.user.external_accounts.add(self.oauth_settings)
        self.user.save()
        self.node.add_addon('github', self.auth_obj)
        self.node_addon = self.node.get_addon('github')
        self.node_addon.user = '******'
        self.node_addon.repo = 'youre-my-best-friend'
        self.node_addon.user_settings = self.user_addon
        self.node_addon.external_account = self.oauth_settings
        self.node_addon.save()
        self.user_addon.oauth_grants[self.node._id] = {self.oauth_settings._id: []}
        self.user_addon.save()

    def build_url(self, **kwargs):
        options = {'payload': jwe.encrypt(jwt.encode({'data': dict(dict(
            action='download',
            nid=self.node._id,
            provider=self.node_addon.config.short_name), **kwargs),
            'exp': timezone.now() + datetime.timedelta(seconds=settings.WATERBUTLER_JWT_EXPIRATION),
        }, settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM), self.JWE_KEY)}
        return api_url_for('get_auth', **options)

    def test_auth_download(self):
        url = self.build_url()
        res = self.app.get(url, auth=self.user.auth)
        data = jwt.decode(jwe.decrypt(res.json['payload'].encode('utf-8'), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM)['data']
        assert_equal(data['auth'], views.make_auth(self.user))
        assert_equal(data['credentials'], self.node_addon.serialize_waterbutler_credentials())
        assert_equal(data['settings'], self.node_addon.serialize_waterbutler_settings())
        expected_url = furl.furl(self.node.api_url_for('create_waterbutler_log', _absolute=True, _internal=True))
        observed_url = furl.furl(data['callback_url'])
        observed_url.port = expected_url.port
        assert_equal(expected_url, observed_url)

    def test_auth_missing_args(self):
        url = self.build_url(cookie=None)
        res = self.app.get(url, expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_auth_bad_cookie(self):
        url = self.build_url(cookie=self.cookie)
        res = self.app.get(url, expect_errors=True)
        assert_equal(res.status_code, 200)
        data = jwt.decode(jwe.decrypt(res.json['payload'].encode('utf-8'), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM)['data']
        assert_equal(data['auth'], views.make_auth(self.user))
        assert_equal(data['credentials'], self.node_addon.serialize_waterbutler_credentials())
        assert_equal(data['settings'], self.node_addon.serialize_waterbutler_settings())
        expected_url = furl.furl(self.node.api_url_for('create_waterbutler_log', _absolute=True, _internal=True))
        observed_url = furl.furl(data['callback_url'])
        observed_url.port = expected_url.port
        assert_equal(expected_url, observed_url)

    def test_auth_cookie(self):
        url = self.build_url(cookie=self.cookie[::-1])
        res = self.app.get(url, expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_auth_missing_addon(self):
        url = self.build_url(provider='queenhub')
        res = self.app.get(url, expect_errors=True, auth=self.user.auth)
        assert_equal(res.status_code, 400)

    @mock.patch('addons.base.views.cas.get_client')
    def test_auth_bad_bearer_token(self, mock_cas_client):
        mock_cas_client.return_value = mock.Mock(profile=mock.Mock(return_value=cas.CasResponse(authenticated=False)))
        url = self.build_url()
        res = self.app.get(url, headers={'Authorization': 'Bearer invalid_access_token'}, expect_errors=True)
        assert_equal(res.status_code, 403)
Пример #41
0
class TestAddonAuth(OsfTestCase):

    def setUp(self):
        super(TestAddonAuth, self).setUp()
        self.user = AuthUserFactory()
        self.auth_obj = Auth(user=self.user)
        self.node = ProjectFactory(creator=self.user)
        self.session = Session(data={'auth_user_id': self.user._id})
        self.session.save()
        self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id)
        self.configure_addon()
        self.JWE_KEY = jwe.kdf(settings.WATERBUTLER_JWE_SECRET.encode('utf-8'), settings.WATERBUTLER_JWE_SALT.encode('utf-8'))

    def configure_addon(self):
        self.user.add_addon('github')
        self.user_addon = self.user.get_addon('github')
        self.oauth_settings = GitHubAccountFactory(display_name='john')
        self.oauth_settings.save()
        self.user.external_accounts.add(self.oauth_settings)
        self.user.save()
        self.node.add_addon('github', self.auth_obj)
        self.node_addon = self.node.get_addon('github')
        self.node_addon.user = '******'
        self.node_addon.repo = 'youre-my-best-friend'
        self.node_addon.user_settings = self.user_addon
        self.node_addon.external_account = self.oauth_settings
        self.node_addon.save()
        self.user_addon.oauth_grants[self.node._id] = {self.oauth_settings._id: []}
        self.user_addon.save()

    def build_url(self, **kwargs):
        options = {'payload': jwe.encrypt(jwt.encode({'data': dict(dict(
            action='download',
            nid=self.node._id,
            provider=self.node_addon.config.short_name), **kwargs),
            'exp': timezone.now() + datetime.timedelta(seconds=settings.WATERBUTLER_JWT_EXPIRATION),
        }, settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM), self.JWE_KEY)}
        return api_url_for('get_auth', **options)

    def test_auth_download(self):
        url = self.build_url()
        res = self.app.get(url, auth=self.user.auth)
        data = jwt.decode(jwe.decrypt(res.json['payload'].encode('utf-8'), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM)['data']
        assert_equal(data['auth'], views.make_auth(self.user))
        assert_equal(data['credentials'], self.node_addon.serialize_waterbutler_credentials())
        assert_equal(data['settings'], self.node_addon.serialize_waterbutler_settings())
        expected_url = furl.furl(self.node.api_url_for('create_waterbutler_log', _absolute=True, _internal=True))
        observed_url = furl.furl(data['callback_url'])
        observed_url.port = expected_url.port
        assert_equal(expected_url, observed_url)

    def test_auth_missing_args(self):
        url = self.build_url(cookie=None)
        res = self.app.get(url, expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_auth_bad_cookie(self):
        url = self.build_url(cookie=self.cookie)
        res = self.app.get(url, expect_errors=True)
        assert_equal(res.status_code, 200)
        data = jwt.decode(jwe.decrypt(res.json['payload'].encode('utf-8'), self.JWE_KEY), settings.WATERBUTLER_JWT_SECRET, algorithm=settings.WATERBUTLER_JWT_ALGORITHM)['data']
        assert_equal(data['auth'], views.make_auth(self.user))
        assert_equal(data['credentials'], self.node_addon.serialize_waterbutler_credentials())
        assert_equal(data['settings'], self.node_addon.serialize_waterbutler_settings())
        expected_url = furl.furl(self.node.api_url_for('create_waterbutler_log', _absolute=True, _internal=True))
        observed_url = furl.furl(data['callback_url'])
        observed_url.port = expected_url.port
        assert_equal(expected_url, observed_url)

    def test_auth_cookie(self):
        url = self.build_url(cookie=self.cookie[::-1])
        res = self.app.get(url, expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_auth_missing_addon(self):
        url = self.build_url(provider='queenhub')
        res = self.app.get(url, expect_errors=True, auth=self.user.auth)
        assert_equal(res.status_code, 400)

    @mock.patch('addons.base.views.cas.get_client')
    def test_auth_bad_bearer_token(self, mock_cas_client):
        mock_cas_client.return_value = mock.Mock(profile=mock.Mock(return_value=cas.CasResponse(authenticated=False)))
        url = self.build_url()
        res = self.app.get(url, headers={'Authorization': 'Bearer invalid_access_token'}, expect_errors=True)
        assert_equal(res.status_code, 403)
Пример #42
0
class TestViewUtils(OsfTestCase):

    def setUp(self):
        super(TestViewUtils, self).setUp()
        self.user = AuthUserFactory()
        self.auth_obj = Auth(user=self.user)
        self.node = ProjectFactory(creator=self.user)
        self.session = Session(data={'auth_user_id': self.user._id})
        self.session.save()
        self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id)
        self.configure_addon()
        self.JWE_KEY = jwe.kdf(settings.WATERBUTLER_JWE_SECRET.encode('utf-8'), settings.WATERBUTLER_JWE_SALT.encode('utf-8'))

    def configure_addon(self):
        self.user.add_addon('github')
        self.user_addon = self.user.get_addon('github')
        self.oauth_settings = GitHubAccountFactory(display_name='john')
        self.oauth_settings.save()
        self.user.external_accounts.add(self.oauth_settings)
        self.user.save()
        self.node.add_addon('github', self.auth_obj)
        self.node_addon = self.node.get_addon('github')
        self.node_addon.user = '******'
        self.node_addon.repo = 'youre-my-best-friend'
        self.node_addon.user_settings = self.user_addon
        self.node_addon.external_account = self.oauth_settings
        self.node_addon.save()
        self.user_addon.oauth_grants[self.node._id] = {self.oauth_settings._id: []}
        self.user_addon.save()

    def test_serialize_addons(self):
        addon_dicts = serialize_addons(self.node, self.auth_obj)

        enabled_addons = [addon for addon in addon_dicts if addon['enabled']]
        assert len(enabled_addons) == 2
        assert enabled_addons[0]['short_name'] == 'github'
        assert enabled_addons[1]['short_name'] == 'osfstorage'

        default_addons = [addon for addon in addon_dicts if addon['default']]
        assert len(default_addons) == 1
        assert default_addons[0]['short_name'] == 'osfstorage'

    def test_include_template_json(self):
        """ Some addons (github, gitlab) need more specialized template infomation so we want to
        ensure we get those extra variables that when the addon is enabled.
        """
        addon_dicts = serialize_addons(self.node, self.auth_obj)

        enabled_addons = [addon for addon in addon_dicts if addon['enabled']]
        assert len(enabled_addons) == 2
        assert enabled_addons[1]['short_name'] == 'osfstorage'
        assert enabled_addons[0]['short_name'] == 'github'
        assert 'node_has_auth' in enabled_addons[0]
        assert 'valid_credentials' in enabled_addons[0]

    def test_collect_node_config_js(self):

        addon_dicts = serialize_addons(self.node, self.auth_obj)

        asset_paths = collect_node_config_js(addon_dicts)

        # Default addons should be in addon dicts, but they have no js assets because you can't
        # connect/disconnect from them, think osfstorage, there's no node-cfg for that.
        default_addons = [addon['short_name'] for addon in addon_dicts if addon['default']]
        assert not any('/{}/'.format(addon) in asset_paths for addon in default_addons)
Пример #43
0
class TestNodeFilesListFiltering(ApiTestCase):
    def setUp(self):
        super(TestNodeFilesListFiltering, self).setUp()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        httpretty.enable()
        # Prep HTTP mocks
        prepare_mock_wb_response(node=self.project,
                                 provider='github',
                                 files=[
                                     {
                                         'name': 'abc',
                                         'path': '/abc/',
                                         'materialized': '/abc/',
                                         'kind': 'folder'
                                     },
                                     {
                                         'name': 'xyz',
                                         'path': '/xyz',
                                         'materialized': '/xyz',
                                         'kind': 'file'
                                     },
                                 ])

    def tearDown(self):
        super(TestNodeFilesListFiltering, self).tearDown()
        httpretty.disable()
        httpretty.reset()

    def add_github(self):
        user_auth = Auth(self.user)
        self.project.add_addon('github', auth=user_auth)
        addon = self.project.get_addon('github')
        addon.repo = 'something'
        addon.user = '******'
        oauth_settings = GitHubAccountFactory()
        oauth_settings.save()
        self.user.add_addon('github')
        self.user.external_accounts.add(oauth_settings)
        self.user.save()
        addon.user_settings = self.user.get_addon('github')
        addon.external_account = oauth_settings
        addon.save()
        self.project.save()
        addon.user_settings.oauth_grants[self.project._id] = {
            oauth_settings._id: []
        }
        addon.user_settings.save()

    def test_node_files_are_filterable_by_name(self):
        url = '/{}nodes/{}/files/github/?filter[name]=xyz'.format(
            API_BASE, self.project._id)
        self.add_github()

        # test create
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 1)  # filters out 'abc'
        assert_equal(res.json['data'][0]['attributes']['name'], 'xyz')

        # test get
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 1)  # filters out 'abc'
        assert_equal(res.json['data'][0]['attributes']['name'], 'xyz')

    def test_node_files_filter_by_name_case_insensitive(self):
        url = '/{}nodes/{}/files/github/?filter[name]=XYZ'.format(
            API_BASE, self.project._id)
        self.add_github()

        # test create
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        # filters out 'abc', but finds 'xyz'
        assert_equal(len(res.json['data']), 1)
        assert_equal(res.json['data'][0]['attributes']['name'], 'xyz')

        # test get
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        # filters out 'abc', but finds 'xyz'
        assert_equal(len(res.json['data']), 1)
        assert_equal(res.json['data'][0]['attributes']['name'], 'xyz')

    def test_node_files_are_filterable_by_path(self):
        url = '/{}nodes/{}/files/github/?filter[path]=abc'.format(
            API_BASE, self.project._id)
        self.add_github()

        # test create
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 1)  # filters out 'xyz'
        assert_equal(res.json['data'][0]['attributes']['name'], 'abc')

        # test get
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 1)  # filters out 'xyz'
        assert_equal(res.json['data'][0]['attributes']['name'], 'abc')

    def test_node_files_are_filterable_by_kind(self):
        url = '/{}nodes/{}/files/github/?filter[kind]=folder'.format(
            API_BASE, self.project._id)
        self.add_github()

        # test create
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 1)  # filters out 'xyz'
        assert_equal(res.json['data'][0]['attributes']['name'], 'abc')

        # test get
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 1)  # filters out 'xyz'
        assert_equal(res.json['data'][0]['attributes']['name'], 'abc')

    def test_node_files_external_provider_can_filter_by_last_touched(self):
        yesterday_stamp = timezone.now() - datetime.timedelta(days=1)
        self.add_github()
        url = '/{}nodes/{}/files/github/?filter[last_touched][gt]={}'.format(
            API_BASE, self.project._id, yesterday_stamp.isoformat())
        # test create
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 2)

        # test get
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 2)

    def test_node_files_osfstorage_cannot_filter_by_last_touched(self):
        yesterday_stamp = timezone.now() - datetime.timedelta(days=1)
        self.file = api_utils.create_test_file(self.project, self.user)

        url = '/{}nodes/{}/files/osfstorage/?filter[last_touched][gt]={}'.format(
            API_BASE, self.project._id, yesterday_stamp.isoformat())

        # test create
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)
        assert_equal(len(res.json['errors']), 1)

        # test get
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 400)
        assert_equal(len(res.json['errors']), 1)
class TestCallbacks(OsfTestCase):
    def setUp(self):

        super(TestCallbacks, self).setUp()

        self.project = ProjectFactory()
        self.consolidated_auth = Auth(self.project.creator)
        self.project.creator.save()
        self.non_authenticator = UserFactory()
        self.non_authenticator.save()
        self.project.save()
        self.project.add_contributor(
            contributor=self.non_authenticator,
            auth=self.consolidated_auth,
        )

        self.project.add_addon('github', auth=self.consolidated_auth)
        self.project.creator.add_addon('github')
        self.external_account = factories.GitHubAccountFactory()
        self.project.creator.external_accounts.add(self.external_account)
        self.project.creator.save()
        self.node_settings = self.project.get_addon('github')
        self.user_settings = self.project.creator.get_addon('github')
        self.node_settings.user_settings = self.user_settings
        self.node_settings.user = '******'
        self.node_settings.repo = 'Sheer-Heart-Attack'
        self.node_settings.external_account = self.external_account
        self.node_settings.save()
        self.node_settings.set_auth
        self.user_settings.oauth_grants[self.project._id] = {
            self.external_account._id: []
        }
        self.user_settings.save()

    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_before_make_public(self, mock_repo):
        mock_repo.side_effect = NotFoundError

        result = self.node_settings.before_make_public(self.project)
        assert_is(result, None)

    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_before_page_load_osf_public_gh_public(self, mock_repo):
        self.project.is_public = True
        self.project.save()
        mock_repo.return_value = Repository.from_json(dumps({'private':
                                                             False}))
        message = self.node_settings.before_page_load(self.project,
                                                      self.project.creator)
        mock_repo.assert_called_with(
            self.node_settings.user,
            self.node_settings.repo,
        )
        assert_false(message)

    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_before_page_load_osf_public_gh_private(self, mock_repo):
        self.project.is_public = True
        self.project.save()
        mock_repo.return_value = Repository.from_json(dumps({'private': True}))
        message = self.node_settings.before_page_load(self.project,
                                                      self.project.creator)
        mock_repo.assert_called_with(
            self.node_settings.user,
            self.node_settings.repo,
        )
        assert_true(message)

    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_before_page_load_osf_private_gh_public(self, mock_repo):
        mock_repo.return_value = Repository.from_json(dumps({'private':
                                                             False}))
        message = self.node_settings.before_page_load(self.project,
                                                      self.project.creator)
        mock_repo.assert_called_with(
            self.node_settings.user,
            self.node_settings.repo,
        )
        assert_true(message)

    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_before_page_load_osf_private_gh_private(self, mock_repo):
        mock_repo.return_value = Repository.from_json(dumps({'private': True}))
        message = self.node_settings.before_page_load(self.project,
                                                      self.project.creator)
        mock_repo.assert_called_with(
            self.node_settings.user,
            self.node_settings.repo,
        )
        assert_false(message)

    def test_before_page_load_not_contributor(self):
        message = self.node_settings.before_page_load(self.project,
                                                      UserFactory())
        assert_false(message)

    def test_before_page_load_not_logged_in(self):
        message = self.node_settings.before_page_load(self.project, None)
        assert_false(message)

    def test_before_remove_contributor_authenticator(self):
        message = self.node_settings.before_remove_contributor(
            self.project, self.project.creator)
        assert_true(message)

    def test_before_remove_contributor_not_authenticator(self):
        message = self.node_settings.before_remove_contributor(
            self.project, self.non_authenticator)
        assert_false(message)

    def test_after_remove_contributor_authenticator_self(self):
        message = self.node_settings.after_remove_contributor(
            self.project, self.project.creator, self.consolidated_auth)
        assert_equal(self.node_settings.user_settings, None)
        assert_true(message)
        assert_not_in('You can re-authenticate', message)

    def test_after_remove_contributor_authenticator_not_self(self):
        auth = Auth(user=self.non_authenticator)
        message = self.node_settings.after_remove_contributor(
            self.project, self.project.creator, auth)
        assert_equal(self.node_settings.user_settings, None)
        assert_true(message)
        assert_in('You can re-authenticate', message)

    def test_after_remove_contributor_not_authenticator(self):
        self.node_settings.after_remove_contributor(self.project,
                                                    self.non_authenticator,
                                                    self.consolidated_auth)
        assert_not_equal(
            self.node_settings.user_settings,
            None,
        )

    def test_after_fork_authenticator(self):
        fork = ProjectFactory()
        clone = self.node_settings.after_fork(
            self.project,
            fork,
            self.project.creator,
        )
        assert_equal(
            self.node_settings.user_settings,
            clone.user_settings,
        )

    def test_after_fork_not_authenticator(self):
        fork = ProjectFactory()
        clone = self.node_settings.after_fork(
            self.project,
            fork,
            self.non_authenticator,
        )
        assert_equal(
            clone.user_settings,
            None,
        )

    def test_after_delete(self):
        self.project.remove_node(Auth(user=self.project.creator))
        # Ensure that changes to node settings have been saved
        self.node_settings.reload()
        assert_true(self.node_settings.user_settings is None)

    @mock.patch('website.archiver.tasks.archive')
    def test_does_not_get_copied_to_registrations(self, mock_archive):
        registration = self.project.register_node(
            schema=get_default_metaschema(),
            auth=Auth(user=self.project.creator),
            draft_registration=DraftRegistrationFactory(
                branched_from=self.project),
        )
        assert_false(registration.has_addon('github'))
Пример #45
0
class TestNodeFilesList(ApiTestCase):
    def setUp(self):
        super(TestNodeFilesList, self).setUp()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        self.private_url = '/{}nodes/{}/files/'.format(API_BASE,
                                                       self.project._id)

        self.user_two = AuthUserFactory()

        self.public_project = ProjectFactory(creator=self.user, is_public=True)
        self.public_url = '/{}nodes/{}/files/'.format(API_BASE,
                                                      self.public_project._id)
        httpretty.enable()

    def tearDown(self):
        super(TestNodeFilesList, self).tearDown()
        httpretty.disable()
        httpretty.reset()

    def add_github(self):
        user_auth = Auth(self.user)
        self.project.add_addon('github', auth=user_auth)
        addon = self.project.get_addon('github')
        addon.repo = 'something'
        addon.user = '******'
        oauth_settings = GitHubAccountFactory()
        oauth_settings.save()
        self.user.add_addon('github')
        self.user.external_accounts.add(oauth_settings)
        self.user.save()
        addon.user_settings = self.user.get_addon('github')
        addon.external_account = oauth_settings
        addon.save()
        self.project.save()
        addon.user_settings.oauth_grants[self.project._id] = {
            oauth_settings._id: []
        }
        addon.user_settings.save()

    def view_only_link(self):
        private_link = PrivateLinkFactory(creator=self.user)
        private_link.nodes.add(self.project)
        private_link.save()
        return private_link

    def _prepare_mock_wb_response(self, node=None, **kwargs):
        prepare_mock_wb_response(node=node or self.project, **kwargs)

    def test_returns_public_files_logged_out(self):
        res = self.app.get(self.public_url, expect_errors=True)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data'][0]['attributes']['provider'],
                     'osfstorage')
        assert_equal(res.content_type, 'application/vnd.api+json')

    def test_returns_public_files_logged_in(self):
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'application/vnd.api+json')
        assert_equal(res.json['data'][0]['attributes']['provider'],
                     'osfstorage')

    def test_returns_storage_addons_link(self):
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_in('storage_addons', res.json['data'][0]['links'])

    def test_returns_file_data(self):
        fobj = self.project.get_addon('osfstorage').get_root().append_file(
            'NewFile')
        fobj.save()
        res = self.app.get('{}osfstorage/{}'.format(self.private_url,
                                                    fobj._id),
                           auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_true(isinstance(res.json['data'], dict))
        assert_equal(res.content_type, 'application/vnd.api+json')
        assert_equal(res.json['data']['attributes']['kind'], 'file')
        assert_equal(res.json['data']['attributes']['name'], 'NewFile')

    def test_returns_osfstorage_folder_version_two(self):
        fobj = self.project.get_addon('osfstorage').get_root().append_folder(
            'NewFolder')
        fobj.save()
        res = self.app.get('{}osfstorage/'.format(self.private_url),
                           auth=self.user.auth)
        assert_equal(res.status_code, 200)

    def test_returns_osf_storage_folder_version_two_point_two(self):
        fobj = self.project.get_addon('osfstorage').get_root().append_folder(
            'NewFolder')
        fobj.save()
        res = self.app.get('{}osfstorage/?version=2.2'.format(
            self.private_url),
                           auth=self.user.auth)
        assert_equal(res.status_code, 200)

    def test_list_returns_folder_data(self):
        fobj = self.project.get_addon('osfstorage').get_root().append_folder(
            'NewFolder')
        fobj.save()
        res = self.app.get('{}osfstorage/'.format(self.private_url, fobj._id),
                           auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 1)
        assert_equal(res.content_type, 'application/vnd.api+json')
        assert_equal(res.json['data'][0]['attributes']['name'], 'NewFolder')

    def test_returns_folder_data(self):
        fobj = self.project.get_addon('osfstorage').get_root().append_folder(
            'NewFolder')
        fobj.save()
        res = self.app.get('{}osfstorage/{}/'.format(self.private_url,
                                                     fobj._id),
                           auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['data']), 0)
        assert_equal(res.content_type, 'application/vnd.api+json')

    def test_returns_private_files_logged_out(self):
        res = self.app.get(self.private_url, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_in('detail', res.json['errors'][0])

    def test_returns_private_files_logged_in_contributor(self):
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'application/vnd.api+json')
        assert_equal(len(res.json['data']), 1)
        assert_equal(res.json['data'][0]['attributes']['provider'],
                     'osfstorage')

    def test_returns_private_files_logged_in_non_contributor(self):
        res = self.app.get(self.private_url,
                           auth=self.user_two.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_in('detail', res.json['errors'][0])

    def test_returns_addon_folders(self):
        user_auth = Auth(self.user)
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_equal(len(res.json['data']), 1)
        assert_equal(res.json['data'][0]['attributes']['provider'],
                     'osfstorage')

        self.project.add_addon('github', auth=user_auth)
        addon = self.project.get_addon('github')
        addon.repo = 'something'
        addon.user = '******'
        oauth_settings = GitHubAccountFactory()
        oauth_settings.save()
        self.user.add_addon('github')
        self.user.external_accounts.add(oauth_settings)
        self.user.save()
        addon.user_settings = self.user.get_addon('github')
        addon.external_account = oauth_settings
        addon.save()
        self.project.save()
        addon.user_settings.oauth_grants[self.project._id] = {
            oauth_settings._id: []
        }
        addon.user_settings.save()
        res = self.app.get(self.private_url, auth=self.user.auth)
        data = res.json['data']
        providers = [item['attributes']['provider'] for item in data]
        assert_equal(len(data), 2)
        assert_in('github', providers)
        assert_in('osfstorage', providers)

    def test_vol_node_files_list(self):
        self._prepare_mock_wb_response(provider='github',
                                       files=[{
                                           'name': 'NewFile'
                                       }])
        self.add_github()
        vol = self.view_only_link()
        url = '/{}nodes/{}/files/github/?view_only={}'.format(
            API_BASE, self.project._id, vol.key)
        res = self.app.get(url, auth=self.user_two.auth)
        wb_request = httpretty.last_request()
        assert_equal(wb_request.querystring, {
            u'view_only': [unicode(vol.key, 'utf-8')],
            u'meta': [u'True']
        })
        assert_equal(res.json['data'][0]['attributes']['name'], 'NewFile')
        assert_equal(res.json['data'][0]['attributes']['provider'], 'github')
        assert_in(vol.key, res.json['data'][0]['links']['info'])
        assert_in(vol.key, res.json['data'][0]['links']['move'])
        assert_in(vol.key, res.json['data'][0]['links']['upload'])
        assert_in(vol.key, res.json['data'][0]['links']['download'])
        assert_in(vol.key, res.json['data'][0]['links']['delete'])

    def test_returns_node_files_list(self):
        self._prepare_mock_wb_response(provider='github',
                                       files=[{
                                           'name': 'NewFile'
                                       }])
        self.add_github()
        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)

        # test create
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.json['data'][0]['attributes']['name'], 'NewFile')
        assert_equal(res.json['data'][0]['attributes']['provider'], 'github')

        # test get
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.json['data'][0]['attributes']['name'], 'NewFile')
        assert_equal(res.json['data'][0]['attributes']['provider'], 'github')

    def test_returns_node_file(self):
        self._prepare_mock_wb_response(provider='github',
                                       files=[{
                                           'name': 'NewFile'
                                       }],
                                       folder=False,
                                       path='/file')
        self.add_github()
        url = '/{}nodes/{}/files/github/file'.format(API_BASE,
                                                     self.project._id)
        res = self.app.get(
            url,
            auth=self.user.auth,
            headers={
                'COOKIE': 'foo=bar;'  # Webtests doesnt support cookies?
            })
        # test create
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['attributes']['name'], 'NewFile')
        assert_equal(res.json['data']['attributes']['provider'], 'github')

        # test get
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['attributes']['name'], 'NewFile')
        assert_equal(res.json['data']['attributes']['provider'], 'github')

    def test_notfound_node_file_returns_folder(self):
        self._prepare_mock_wb_response(provider='github',
                                       files=[{
                                           'name': 'NewFile'
                                       }],
                                       path='/file')
        url = '/{}nodes/{}/files/github/file'.format(API_BASE,
                                                     self.project._id)
        res = self.app.get(
            url,
            auth=self.user.auth,
            expect_errors=True,
            headers={'COOKIE': 'foo=bar;'}  # Webtests doesnt support cookies?
        )
        assert_equal(res.status_code, 404)

    def test_notfound_node_folder_returns_file(self):
        self._prepare_mock_wb_response(provider='github',
                                       files=[{
                                           'name': 'NewFile'
                                       }],
                                       folder=False,
                                       path='/')

        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(
            url,
            auth=self.user.auth,
            expect_errors=True,
            headers={'COOKIE': 'foo=bar;'}  # Webtests doesnt support cookies?
        )
        assert_equal(res.status_code, 404)

    def test_waterbutler_server_error_returns_503(self):
        self._prepare_mock_wb_response(status_code=500)
        self.add_github()
        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(
            url,
            auth=self.user.auth,
            expect_errors=True,
            headers={'COOKIE': 'foo=bar;'}  # Webtests doesnt support cookies?
        )
        assert_equal(res.status_code, 503)

    def test_waterbutler_invalid_data_returns_503(self):
        wb_url = waterbutler_api_url_for(self.project._id,
                                         provider='github',
                                         path='/',
                                         meta=True)
        self.add_github()
        httpretty.register_uri(httpretty.GET,
                               wb_url,
                               body=json.dumps({}),
                               status=400)
        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 503)

    def test_handles_unauthenticated_waterbutler_request(self):
        self._prepare_mock_wb_response(status_code=401)
        self.add_github()
        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_in('detail', res.json['errors'][0])

    def test_handles_notfound_waterbutler_request(self):
        invalid_provider = 'gilkjadsflhub'
        self._prepare_mock_wb_response(status_code=404,
                                       provider=invalid_provider)
        url = '/{}nodes/{}/files/{}/'.format(API_BASE, self.project._id,
                                             invalid_provider)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 404)
        assert_in('detail', res.json['errors'][0])

    def test_handles_request_to_provider_not_configured_on_project(self):
        provider = 'box'
        url = '/{}nodes/{}/files/{}/'.format(API_BASE, self.project._id,
                                             provider)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_false(self.project.get_addon(provider))
        assert_equal(res.status_code, 404)
        assert_equal(
            res.json['errors'][0]['detail'],
            'The {} provider is not configured for this project.'.format(
                provider))

    def test_handles_bad_waterbutler_request(self):
        wb_url = waterbutler_api_url_for(self.project._id,
                                         provider='github',
                                         path='/',
                                         meta=True)
        httpretty.register_uri(httpretty.GET,
                               wb_url,
                               body=json.dumps({}),
                               status=418)
        self.add_github()
        url = '/{}nodes/{}/files/github/'.format(API_BASE, self.project._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 503)
        assert_in('detail', res.json['errors'][0])

    def test_files_list_contains_relationships_object(self):
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert 'relationships' in res.json['data'][0]
Пример #46
0
class TestGitLabViews(OsfTestCase):

    def setUp(self):
        super(TestGitLabViews, self).setUp()
        self.user = AuthUserFactory()
        self.consolidated_auth = Auth(user=self.user)

        self.project = ProjectFactory(creator=self.user)
        self.non_authenticator = UserFactory()
        self.project.add_contributor(
            contributor=self.non_authenticator,
            auth=self.consolidated_auth,
        )
        self.project.save()
        self.project.add_addon('gitlab', auth=self.consolidated_auth)
        self.project.creator.add_addon('gitlab')
        self.project.creator.external_accounts.add(GitLabAccountFactory())
        self.project.creator.save()

        self.gitlab = create_mock_gitlab(user='******', private=False)

        self.node_settings = self.project.get_addon('gitlab')
        self.node_settings.user_settings = self.project.creator.get_addon('gitlab')
        # Set the node addon settings to correspond to the values of the mock repo
        self.node_settings.user = '******'
        self.node_settings.repo = 'mock-repo'
        self.node_settings.repo_id = 1748448
        self.node_settings.save()

    def _get_sha_for_branch(self, branch=None, mock_branches=None):
        gitlab_mock = self.gitlab
        if mock_branches is None:
            mock_branches = gitlab_mock.branches
        if branch is None:  # Get default branch name
            branch = self.gitlab.repo.default_branch
        for each in mock_branches:
            if each.name == branch:
                branch_sha = each.commit['id']
        return branch_sha

    # Tests for _get_refs
    @mock.patch('addons.gitlab.api.GitLabClient.branches')
    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_get_refs_defaults(self, mock_repo, mock_branches):
        gitlab_mock = self.gitlab
        mock_repo.return_value = gitlab_mock.repo
        mock_branches.return_value = gitlab_mock.branches.return_value
        branch, sha, branches = utils.get_refs(self.node_settings)
        assert_equal(
            branch,
            gitlab_mock.repo.default_branch
        )
        assert_equal(sha, branches[0].commit['id'])  # Get refs for default branch
        assert_equal(
            branches,
            gitlab_mock.branches.return_value
        )

    @mock.patch('addons.gitlab.api.GitLabClient.branches')
    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_get_refs_branch(self, mock_repo, mock_branches):
        gitlab_mock = self.gitlab
        mock_repo.return_value = gitlab_mock.repo.return_value
        mock_branches.return_value = gitlab_mock.branches.return_value
        branch, sha, branches = utils.get_refs(self.node_settings, 'master')
        assert_equal(branch, 'master')
        assert_equal(sha, branches[0].commit['id'])
        assert_equal(
            branches,
            gitlab_mock.branches.return_value
        )

    def test_before_fork(self):
        url = self.project.api_url + 'fork/before/'
        res = self.app.get(url, auth=self.user.auth).maybe_follow()
        assert_equal(len(res.json['prompts']), 1)

    @mock.patch('addons.gitlab.models.UserSettings.has_auth')
    def test_before_register(self, mock_has_auth):
        mock_has_auth.return_value = True
        url = self.project.api_url + 'beforeregister/'
        res = self.app.get(url, auth=self.user.auth).maybe_follow()
        assert_true('GitLab' in res.json['prompts'][1])

    def test_get_refs_sha_no_branch(self):
        with assert_raises(HTTPError):
            utils.get_refs(self.node_settings, sha='12345')

    # Tests for _check_permissions
    # make a user with no authorization; make sure check_permissions returns false
    def test_permissions_no_auth(self):
        gitlab_mock = self.gitlab
        # project is set to private right now
        connection = gitlab_mock
        non_authenticated_user = UserFactory()
        non_authenticated_auth = Auth(user=non_authenticated_user)
        branch = 'master'
        assert_false(check_permissions(self.node_settings, non_authenticated_auth, connection, branch))

    # make a repository that doesn't allow push access for this user;
    # make sure check_permissions returns false
    @mock.patch('addons.gitlab.models.UserSettings.has_auth')
    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_permissions_no_access(self, mock_repo, mock_has_auth):
        gitlab_mock = self.gitlab
        mock_has_auth.return_value = True
        connection = gitlab_mock
        branch = 'master'
        mock_repository = mock.Mock(**{
            'user': '******',
            'repo': 'mock-repo',
            'permissions': {
                'project_access': {'access_level': 20, 'notification_level': 3}
            },
        })
        mock_repo.attributes.return_value = mock_repository
        assert_false(check_permissions(self.node_settings, self.consolidated_auth, connection, branch, repo=mock_repository))

    # make a branch with a different commit than the commit being passed into check_permissions
    @mock.patch('addons.gitlab.models.UserSettings.has_auth')
    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_permissions_not_head(self, mock_repo, mock_has_auth):
        gitlab_mock = self.gitlab
        mock_has_auth.return_value = True
        connection = gitlab_mock
        mock_branch = mock.Mock(**{
            'commit': {'id': '67890'}
        })
        connection.branches.return_value = mock_branch
        sha = '12345'
        assert_false(check_permissions(self.node_settings, self.consolidated_auth, connection, mock_branch, sha=sha))

    # make sure permissions are not granted for editing a registration
    @mock.patch('addons.gitlab.models.UserSettings.has_auth')
    def test_permissions(self, mock_has_auth):
        gitlab_mock = self.gitlab
        mock_has_auth.return_value = True
        connection = gitlab_mock
        with mock.patch('osf.models.node.AbstractNode.is_registration', new_callable=mock.PropertyMock) as mock_is_reg:
            mock_is_reg.return_value = True
            assert_false(check_permissions(self.node_settings, self.consolidated_auth, connection, 'master'))

    def check_hook_urls(self, urls, node, path, sha):
        url = node.web_url_for('addon_view_or_download_file', path=path, provider='gitlab')
        expected_urls = {
            'view': '{0}?branch={1}'.format(url, sha),
            'download': '{0}?action=download&branch={1}'.format(url, sha)
        }

        assert_equal(urls['view'], expected_urls['view'])
        assert_equal(urls['download'], expected_urls['download'])

    @mock.patch('addons.gitlab.views.verify_hook_signature')
    @mock.patch('addons.gitlab.api.GitLabClient.repo')
    def test_hook_callback_add_file_not_thro_osf(self, mock_repo, mock_verify):
        gitlab_mock = self.gitlab
        gitlab_mock.repo = mock_repo
        url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id)
        timestamp = str(datetime.datetime.utcnow())
        self.app.post_json(
            url,
            {
                'test': True,
                'commits': [{
                    'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                    'distinct': True,
                    'message': 'foo',
                    'timestamp': timestamp,
                    'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                    'author': {'name': 'Illidan', 'email': '*****@*****.**'},
                    'committer': {'name': 'Testor', 'email': '*****@*****.**', 'username': '******'},
                    'added': ['PRJWN3TV'],
                    'removed': [],
                    'modified': [],
                }]
            },
            content_type='application/json',
        ).maybe_follow()
        self.project.reload()
        assert_equal(self.project.logs.latest().action, 'gitlab_file_added')
        urls = self.project.logs.latest().params['urls']
        self.check_hook_urls(
            urls,
            self.project,
            path='PRJWN3TV',
            sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
        )

    @mock.patch('addons.gitlab.views.verify_hook_signature')
    def test_hook_callback_modify_file_not_thro_osf(self, mock_verify):
        url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id)
        timestamp = str(datetime.datetime.utcnow())
        self.app.post_json(
            url,
            {'test': True,
                 'commits': [{'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                              'distinct': True,
                              'message': ' foo',
                              'timestamp': timestamp,
                              'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                              'author': {'name': 'Illidan', 'email': '*****@*****.**'},
                              'committer': {'name': 'Testor', 'email': '*****@*****.**',
                                            'username': '******'},
                              'added': [], 'removed':[], 'modified':['PRJWN3TV']}]},
            content_type='application/json').maybe_follow()
        self.project.reload()
        assert_equal(self.project.logs.latest().action, 'gitlab_file_updated')
        urls = self.project.logs.latest().params['urls']
        self.check_hook_urls(
            urls,
            self.project,
            path='PRJWN3TV',
            sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
        )

    @mock.patch('addons.gitlab.views.verify_hook_signature')
    def test_hook_callback_remove_file_not_thro_osf(self, mock_verify):
        url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id)
        timestamp = str(datetime.datetime.utcnow())
        self.app.post_json(
            url,
            {'test': True,
             'commits': [{'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                          'distinct': True,
                          'message': 'foo',
                          'timestamp': timestamp,
                          'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                          'author': {'name': 'Illidan', 'email': '*****@*****.**'},
                          'committer': {'name': 'Testor', 'email': '*****@*****.**', 'username': '******'},
                          'added': [], 'removed': ['PRJWN3TV'], 'modified':[]}]},
            content_type='application/json').maybe_follow()
        self.project.reload()
        assert_equal(self.project.logs.latest().action, 'gitlab_file_removed')
        urls = self.project.logs.latest().params['urls']
        assert_equal(urls, {})

    @mock.patch('addons.gitlab.views.verify_hook_signature')
    def test_hook_callback_add_file_thro_osf(self, mock_verify):
        url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id)
        self.app.post_json(
            url,
            {'test': True,
             'commits': [{'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                          'distinct': True,
                          'message': 'Added via the Open Science Framework',
                          'timestamp': '2014-01-08T14:15:51-08:00',
                          'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                          'author': {'name': 'Illidan', 'email': '*****@*****.**'},
                          'committer': {'name': 'Testor', 'email': '*****@*****.**', 'username': '******'},
                          'added': ['PRJWN3TV'], 'removed':[], 'modified':[]}]},
            content_type='application/json').maybe_follow()
        self.project.reload()
        assert_not_equal(self.project.logs.latest().action, 'gitlab_file_added')

    @mock.patch('addons.gitlab.views.verify_hook_signature')
    def test_hook_callback_modify_file_thro_osf(self, mock_verify):
        url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id)
        self.app.post_json(
            url,
            {'test': True,
             'commits': [{'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                          'distinct': True,
                          'message': 'Updated via the Open Science Framework',
                          'timestamp': '2014-01-08T14:15:51-08:00',
                          'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                          'author': {'name': 'Illidan', 'email': '*****@*****.**'},
                          'committer': {'name': 'Testor', 'email': '*****@*****.**', 'username': '******'},
                          'added': [], 'removed':[], 'modified':['PRJWN3TV']}]},
            content_type='application/json').maybe_follow()
        self.project.reload()
        assert_not_equal(self.project.logs.latest().action, 'gitlab_file_updated')

    @mock.patch('addons.gitlab.views.verify_hook_signature')
    def test_hook_callback_remove_file_thro_osf(self, mock_verify):
        url = '/api/v1/project/{0}/gitlab/hook/'.format(self.project._id)
        self.app.post_json(
            url,
            {'test': True,
             'commits': [{'id': 'b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                          'distinct': True,
                          'message': 'Deleted via the Open Science Framework',
                          'timestamp': '2014-01-08T14:15:51-08:00',
                          'url': 'https://gitlab.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce',
                          'author': {'name': 'Illidan', 'email': '*****@*****.**'},
                          'committer': {'name': 'Testor', 'email': '*****@*****.**', 'username': '******'},
                          'added': [], 'removed':['PRJWN3TV'], 'modified':[]}]},
            content_type='application/json').maybe_follow()
        self.project.reload()
        assert_not_equal(self.project.logs.latest().action, 'gitlab_file_removed')
Пример #47
0
class TestCreateBucket(S3AddonTestCase, OsfTestCase):

    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('eu-central-1'))
        assert_true(validate_bucket_location('ca-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('sa-east-1'))
        assert_true(validate_bucket_location('eu-west-1'))
        assert_true(validate_bucket_location('eu-west-2'))

    @mock.patch('addons.s3.views.utils.create_bucket')
    @mock.patch('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('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('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"}')
Пример #48
0
class TestCallbacks(OsfTestCase):

    def setUp(self):

        super(TestCallbacks, self).setUp()

        self.project = ProjectFactory()
        self.consolidated_auth = Auth(self.project.creator)
        self.project.creator.save()
        self.non_authenticator = UserFactory()
        self.non_authenticator.save()
        self.project.save()
        self.project.add_contributor(
            contributor=self.non_authenticator,
            auth=self.consolidated_auth,
        )

        self.project.add_addon('github', auth=self.consolidated_auth)
        self.project.creator.add_addon('github')
        self.external_account = factories.GitHubAccountFactory()
        self.project.creator.external_accounts.add(self.external_account)
        self.project.creator.save()
        self.node_settings = self.project.get_addon('github')
        self.user_settings = self.project.creator.get_addon('github')
        self.node_settings.user_settings = self.user_settings
        self.node_settings.user = '******'
        self.node_settings.repo = 'Sheer-Heart-Attack'
        self.node_settings.external_account = self.external_account
        self.node_settings.save()
        self.node_settings.set_auth
        self.user_settings.oauth_grants[self.project._id] = {self.external_account._id: []}
        self.user_settings.save()

    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_before_make_public(self, mock_repo):
        mock_repo.side_effect = NotFoundError

        result = self.node_settings.before_make_public(self.project)
        assert_is(result, None)

    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_before_page_load_osf_public_gh_public(self, mock_repo):
        self.project.is_public = True
        self.project.save()
        mock_repo.return_value = Repository.from_json({'private': False})
        message = self.node_settings.before_page_load(self.project, self.project.creator)
        mock_repo.assert_called_with(
            self.node_settings.user,
            self.node_settings.repo,
        )
        assert_false(message)

    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_before_page_load_osf_public_gh_private(self, mock_repo):
        self.project.is_public = True
        self.project.save()
        mock_repo.return_value = Repository.from_json({'private': True})
        message = self.node_settings.before_page_load(self.project, self.project.creator)
        mock_repo.assert_called_with(
            self.node_settings.user,
            self.node_settings.repo,
        )
        assert_true(message)

    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_before_page_load_osf_private_gh_public(self, mock_repo):
        mock_repo.return_value = Repository.from_json({'private': False})
        message = self.node_settings.before_page_load(self.project, self.project.creator)
        mock_repo.assert_called_with(
            self.node_settings.user,
            self.node_settings.repo,
        )
        assert_true(message)

    @mock.patch('addons.github.api.GitHubClient.repo')
    def test_before_page_load_osf_private_gh_private(self, mock_repo):
        mock_repo.return_value = Repository.from_json({'private': True})
        message = self.node_settings.before_page_load(self.project, self.project.creator)
        mock_repo.assert_called_with(
            self.node_settings.user,
            self.node_settings.repo,
        )
        assert_false(message)

    def test_before_page_load_not_contributor(self):
        message = self.node_settings.before_page_load(self.project, UserFactory())
        assert_false(message)

    def test_before_page_load_not_logged_in(self):
        message = self.node_settings.before_page_load(self.project, None)
        assert_false(message)

    def test_before_remove_contributor_authenticator(self):
        message = self.node_settings.before_remove_contributor(
            self.project, self.project.creator
        )
        assert_true(message)

    def test_before_remove_contributor_not_authenticator(self):
        message = self.node_settings.before_remove_contributor(
            self.project, self.non_authenticator
        )
        assert_false(message)

    def test_after_remove_contributor_authenticator_self(self):
        message = self.node_settings.after_remove_contributor(
            self.project, self.project.creator, self.consolidated_auth
        )
        assert_equal(
            self.node_settings.user_settings,
            None
        )
        assert_true(message)
        assert_not_in('You can re-authenticate', message)

    def test_after_remove_contributor_authenticator_not_self(self):
        auth = Auth(user=self.non_authenticator)
        message = self.node_settings.after_remove_contributor(
            self.project, self.project.creator, auth
        )
        assert_equal(
            self.node_settings.user_settings,
            None
        )
        assert_true(message)
        assert_in('You can re-authenticate', message)

    def test_after_remove_contributor_not_authenticator(self):
        self.node_settings.after_remove_contributor(
            self.project, self.non_authenticator, self.consolidated_auth
        )
        assert_not_equal(
            self.node_settings.user_settings,
            None,
        )

    def test_after_fork_authenticator(self):
        fork = ProjectFactory()
        clone = self.node_settings.after_fork(
            self.project, fork, self.project.creator,
        )
        assert_equal(
            self.node_settings.user_settings,
            clone.user_settings,
        )

    def test_after_fork_not_authenticator(self):
        fork = ProjectFactory()
        clone = self.node_settings.after_fork(
            self.project, fork, self.non_authenticator,
        )
        assert_equal(
            clone.user_settings,
            None,
        )

    def test_after_delete(self):
        self.project.remove_node(Auth(user=self.project.creator))
        # Ensure that changes to node settings have been saved
        self.node_settings.reload()
        assert_true(self.node_settings.user_settings is None)

    @mock.patch('website.archiver.tasks.archive')
    def test_does_not_get_copied_to_registrations(self, mock_archive):
        registration = self.project.register_node(
            schema=get_default_metaschema(),
            auth=Auth(user=self.project.creator),
            data='hodor',
        )
        assert_false(registration.has_addon('github'))
Пример #49
0
class TestAddonLogs(OsfTestCase):

    def setUp(self):
        super(TestAddonLogs, self).setUp()
        self.user = AuthUserFactory()
        self.auth_obj = Auth(user=self.user)
        self.node = ProjectFactory(creator=self.user)
        self.session = Session(data={'auth_user_id': self.user._id})
        self.session.save()
        self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id)
        self.configure_addon()

    def configure_addon(self):
        self.user.add_addon('github')
        self.user_addon = self.user.get_addon('github')
        self.oauth_settings = GitHubAccountFactory(display_name='john')
        self.oauth_settings.save()
        self.user.external_accounts.add(self.oauth_settings)
        self.user.save()
        self.node.add_addon('github', self.auth_obj)
        self.node_addon = self.node.get_addon('github')
        self.node_addon.user = '******'
        self.node_addon.repo = 'youre-my-best-friend'
        self.node_addon.user_settings = self.user_addon
        self.node_addon.external_account = self.oauth_settings
        self.node_addon.save()
        self.user_addon.oauth_grants[self.node._id] = {self.oauth_settings._id: []}
        self.user_addon.save()

    def configure_osf_addon(self):
        self.project = ProjectFactory(creator=self.user)
        self.node_addon = self.project.get_addon('osfstorage')
        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')
    @mock.patch('requests.get',{'code': 404, 'referrer': None,'message_short': 'Page not found'})
    def test_add_log_timestamptoken(self, mock_perform):
        from osf.models import RdmFileTimestamptokenVerifyResult, NodeLog
        from api_tests.utils import create_test_file
        from website.views import userkey_generation
        result_list1_count = RdmFileTimestamptokenVerifyResult.objects.filter(project_id=self.node._id).count()
        nodelog_count1 = NodeLog.objects.all().count()
        path = 'pizza'
        url = self.node.api_url_for('create_waterbutler_log')
        userkey_generation(self.user._id)
        file_node = create_test_file(node=self.node, user=self.user, filename=path)
        file_node._path = '/' + path
        file_node.save()
        metadata = {
            'path': path,
            'provider': 'osfstorage',
            'name': path,
            'materialized': '/' + path,
            'extra': {
                'version': 1
            }
        }
        payload = self.build_payload(metadata=metadata)
        logging.info('---test_add_log_timestamptoken.payload: {}'.format(payload))
        nlogs = self.node.logs.count()
        
        self.app.put_json(url, payload, headers={'Content-Type': 'application/json'})
        self.node.reload()
        assert_equal(self.node.logs.count(), nlogs + 1)
        nodelog_count2 = NodeLog.objects.all().count()
        assert_equal(nodelog_count1 + 1, nodelog_count2)
        result_list2 = RdmFileTimestamptokenVerifyResult.objects.filter(project_id=self.node._id)
        assert_true(mock_perform.called, 'perform not called')

        ## tearDown
        import os
        from api.base import settings as api_settings
        from osf.models import RdmUserKey
        rdmuserkey_pvt_key = RdmUserKey.objects.get(guid=self.user.id, key_kind=api_settings.PRIVATE_KEY_VALUE)
        pvt_key_path = os.path.join(api_settings.KEY_SAVE_PATH, rdmuserkey_pvt_key.key_name)
        os.remove(pvt_key_path)
        rdmuserkey_pvt_key.delete()

        rdmuserkey_pub_key = RdmUserKey.objects.get(guid=self.user.id, key_kind=api_settings.PUBLIC_KEY_VALUE)
        pub_key_path = os.path.join(api_settings.KEY_SAVE_PATH, rdmuserkey_pub_key.key_name)
        os.remove(pub_key_path)
        rdmuserkey_pub_key.delete()

    @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 = self.node.logs.count()
        self.app.put_json(url, payload, headers={'Content-Type': 'application/json'})
        self.node.reload()
        assert_equal(self.node.logs.count(), 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 = self.node.logs.count()
        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(self.node.logs.count(), 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 = self.node.logs.count()
        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(self.node.logs.count(), 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 = node.logs.count()
        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(node.logs.count(), 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 = self.node.logs.count()
        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(self.node.logs.count(), nlogs)

    def test_action_file_rename(self):
        url = self.node.api_url_for('create_waterbutler_log')
        payload = self.build_payload(
            action='rename',
            metadata={
                'path': 'foo',
            },
            source={
                'materialized': 'foo',
                'provider': 'github',
                'node': {'_id': self.node._id},
                'name': 'new.txt',
                'kind': 'file',
            },
            destination={
                'path': 'foo',
                'materialized': 'foo',
                'provider': 'github',
                'node': {'_id': self.node._id},
                'name': 'old.txt',
                'kind': 'file',
            },
        )
        self.app.put_json(
            url,
            payload,
            headers={'Content-Type': 'application/json'}
        )
        self.node.reload()

        assert_equal(
            self.node.logs.latest().action,
            'github_addon_file_renamed',
        )

    def test_action_downloads(self):
        url = self.node.api_url_for('create_waterbutler_log')
        download_actions=('download_file', 'download_zip')
        for action in download_actions:
            payload = self.build_payload(metadata={'path': 'foo'}, action=action)
            nlogs = self.node.logs.count()
            res = self.app.put_json(
                url,
                payload,
                headers={'Content-Type': 'application/json'},
                expect_errors=False,
            )
            assert_equal(res.status_code, 200)

        self.node.reload()
        assert_equal(self.node.logs.count(), nlogs)

    def test_add_file_osfstorage_log(self):
        self.configure_osf_addon()
        path = 'pizza'
        url = self.node.api_url_for('create_waterbutler_log')
        payload = self.build_payload(metadata={'materialized': path, 'kind': 'file', 'path': path})
        nlogs = self.node.logs.count()
        self.app.put_json(url, payload, headers={'Content-Type': 'application/json'})
        self.node.reload()
        assert_equal(self.node.logs.count(), nlogs + 1)
        assert('urls' in self.node.logs.filter(action='osf_storage_file_added')[0].params)

    def test_add_folder_osfstorage_log(self):
        self.configure_osf_addon()
        path = 'pizza'
        url = self.node.api_url_for('create_waterbutler_log')
        payload = self.build_payload(metadata={'materialized': path, 'kind': 'folder', 'path': path})
        nlogs = self.node.logs.count()
        self.app.put_json(url, payload, headers={'Content-Type': 'application/json'})
        self.node.reload()
        assert_equal(self.node.logs.count(), nlogs + 1)
        assert('urls' not in self.node.logs.filter(action='osf_storage_file_added')[0].params)
Пример #50
0
class TestAddonLogs(OsfTestCase):

    def setUp(self):
        super(TestAddonLogs, self).setUp()
        self.user = AuthUserFactory()
        self.auth_obj = Auth(user=self.user)
        self.node = ProjectFactory(creator=self.user)
        self.session = Session(data={'auth_user_id': self.user._id})
        self.session.save()
        self.cookie = itsdangerous.Signer(settings.SECRET_KEY).sign(self.session._id)
        self.configure_addon()

    def configure_addon(self):
        self.user.add_addon('github')
        self.user_addon = self.user.get_addon('github')
        self.oauth_settings = GitHubAccountFactory(display_name='john')
        self.oauth_settings.save()
        self.user.external_accounts.add(self.oauth_settings)
        self.user.save()
        self.node.add_addon('github', self.auth_obj)
        self.node_addon = self.node.get_addon('github')
        self.node_addon.user = '******'
        self.node_addon.repo = 'youre-my-best-friend'
        self.node_addon.user_settings = self.user_addon
        self.node_addon.external_account = self.oauth_settings
        self.node_addon.save()
        self.user_addon.oauth_grants[self.node._id] = {self.oauth_settings._id: []}
        self.user_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 = self.node.logs.count()
        self.app.put_json(url, payload, headers={'Content-Type': 'application/json'})
        self.node.reload()
        assert_equal(self.node.logs.count(), 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 = self.node.logs.count()
        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(self.node.logs.count(), 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 = self.node.logs.count()
        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(self.node.logs.count(), 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 = node.logs.count()
        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(node.logs.count(), 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 = self.node.logs.count()
        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(self.node.logs.count(), nlogs)

    def test_action_file_rename(self):
        url = self.node.api_url_for('create_waterbutler_log')
        payload = self.build_payload(
            action='rename',
            metadata={
                'path': 'foo',
            },
            source={
                'materialized': 'foo',
                'provider': 'github',
                'node': {'_id': self.node._id},
                'name': 'new.txt',
                'kind': 'file',
            },
            destination={
                'path': 'foo',
                'materialized': 'foo',
                'provider': 'github',
                'node': {'_id': self.node._id},
                'name': 'old.txt',
                'kind': 'file',
            },
        )
        self.app.put_json(
            url,
            payload,
            headers={'Content-Type': 'application/json'}
        )
        self.node.reload()

        assert_equal(
            self.node.logs.latest().action,
            'github_addon_file_renamed',
        )
Пример #51
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 = GitHubAccountFactory()
        self.oauth.save()

        self.user.external_accounts.add(self.oauth)
        self.user.save()

        self.node_addon.user_settings = self.user_addon
        self.node_addon.external_account = self.oauth
        self.node_addon.repo = 'Truth'
        self.node_addon.user = '******'
        self.node_addon.save()

        self.user_addon.oauth_grants[self.project._id] = {self.oauth._id: []}
        self.user_addon.save()

    def set_sentry(status):
        def wrapper(func):
            @functools.wraps(func)
            def wrapped(*args, **kwargs):
                enabled, sentry.enabled = sentry.enabled, status
                func(*args, **kwargs)
                sentry.enabled = enabled

            return wrapped

        return wrapper

    with_sentry = set_sentry(True)

    def get_test_file(self):
        version = file_models.FileVersion(identifier='1')
        version.save()
        ret = GithubFile(
            name='Test',
            node=self.project,
            path='/test/Test',
            materialized_path='/test/Test',
        )
        ret.save()
        ret.versions.add(version)
        return ret

    def get_second_test_file(self):
        version = file_models.FileVersion(identifier='1')
        version.save()
        ret = GithubFile(
            name='Test2',
            node=self.project,
            path='/test/Test2',
            materialized_path='/test/Test2',
        )
        ret.save()
        ret.versions.add(version)
        return ret

    def get_mako_return(self):
        ret = serialize_node(self.project, Auth(self.user), primary=True)
        ret.update({
            'error': '',
            'provider': '',
            'file_path': '',
            'sharejs_uuid': '',
            'private': '',
            'urls': {
                'files': '',
                'render': '',
                'sharejs': '',
                'mfr': '',
                'profile_image': '',
                'external': '',
                'archived_from': '',
            },
            'size': '',
            'extra': '',
            'file_name': '',
            'materialized_path': '',
            'file_id': '',
        })
        ret.update(rubeus.collect_addon_assets(self.project))
        return ret

    def test_redirects_to_guid(self):
        file_node = self.get_test_file()
        guid = file_node.get_guid(create=True)

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

        assert_equals(resp.status_code, 302)
        assert_equals(resp.location, 'http://*****:*****@mock.patch('addons.base.views.addon_view_file')
    def test_action_view_calls_view_file(self, mock_view_file):
        self.user.reload()
        self.project.reload()

        file_node = self.get_test_file()
        guid = file_node.get_guid(create=True)

        mock_view_file.return_value = self.get_mako_return()

        self.app.get('/{}/?action=view'.format(guid._id), auth=self.user.auth)

        args, kwargs = mock_view_file.call_args
        assert_equals(kwargs, {})
        assert_equals(args[0].user._id, self.user._id)
        assert_equals(args[1], self.project)
        assert_equals(args[2], file_node)
        assert_true(isinstance(args[3], file_node.touch(None).__class__))

    @mock.patch('addons.base.views.addon_view_file')
    def test_no_action_calls_view_file(self, mock_view_file):
        self.user.reload()
        self.project.reload()

        file_node = self.get_test_file()
        guid = file_node.get_guid(create=True)

        mock_view_file.return_value = self.get_mako_return()

        self.app.get('/{}/'.format(guid._id), auth=self.user.auth)

        args, kwargs = mock_view_file.call_args
        assert_equals(kwargs, {})
        assert_equals(args[0].user._id, self.user._id)
        assert_equals(args[1], self.project)
        assert_equals(args[2], file_node)
        assert_true(isinstance(args[3], file_node.touch(None).__class__))

    def test_download_create_guid(self):
        file_node = self.get_test_file()
        assert_is(file_node.get_guid(), None)

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

        assert_true(file_node.get_guid())

    def test_view_file_does_not_delete_file_when_requesting_invalid_version(self):
        with mock.patch('addons.github.models.NodeSettings.is_private',
                        new_callable=mock.PropertyMock) as mock_is_private:
            mock_is_private.return_value = False

            file_node = self.get_test_file()
            assert_is(file_node.get_guid(), None)

            url = self.project.web_url_for(
                'addon_view_or_download_file',
                path=file_node.path.strip('/'),
                provider='github',
            )
            # First view generated GUID
            self.app.get(url, auth=self.user.auth)

            self.app.get(url + '?version=invalid', auth=self.user.auth, expect_errors=True)

            assert_is_not_none(BaseFileNode.load(file_node._id))
            assert_is_none(TrashedFileNode.load(file_node._id))

    def test_unauthorized_addons_raise(self):
        path = 'cloudfiles'
        self.node_addon.user_settings = None
        self.node_addon.save()

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

        assert_equals(resp.status_code, 401)

    def test_nonstorage_addons_raise(self):
        resp = self.app.get(
            self.project.web_url_for(
                'addon_view_or_download_file',
                path='sillywiki',
                provider='wiki',
                action='download'
            ),
            auth=self.user.auth,
            expect_errors=True
        )

        assert_equals(resp.status_code, 400)

    def test_head_returns_url_and_redriect(self):
        file_node = self.get_test_file()
        guid = file_node.get_guid(create=True)

        resp = self.app.head('/{}/'.format(guid._id), auth=self.user.auth)
        location = furl.furl(resp.location)
        assert_equals(resp.status_code, 302)
        assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, version=''))

    def test_head_returns_url_with_version_and_redirect(self):
        file_node = self.get_test_file()
        guid = file_node.get_guid(create=True)

        resp = self.app.head('/{}/?revision=1&foo=bar'.format(guid._id), auth=self.user.auth)
        location = furl.furl(resp.location)
        # Note: version is added but us but all other url params are added as well
        assert_equals(resp.status_code, 302)
        assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, revision=1, version='', foo='bar'))

    def test_nonexistent_addons_raise(self):
        path = 'cloudfiles'
        self.project.delete_addon('github', Auth(self.user))
        self.project.save()

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

        assert_equals(resp.status_code, 400)

    def test_unauth_addons_raise(self):
        path = 'cloudfiles'
        self.node_addon.user_settings = None
        self.node_addon.save()

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

        assert_equals(resp.status_code, 401)

    def test_delete_action_creates_trashed_file_node(self):
        file_node = self.get_test_file()
        payload = {
            'provider': file_node.provider,
            'metadata': {
                'path': '/test/Test',
                'materialized': '/test/Test'
            }
        }
        views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload)
        assert_false(GithubFileNode.load(file_node._id))
        assert_true(TrashedFileNode.load(file_node._id))

    def test_delete_action_for_folder_deletes_subfolders_and_creates_trashed_file_nodes(self):
        file_node = self.get_test_file()
        subfolder = GithubFolder(
            name='folder',
            node=self.project,
            path='/test/folder/',
            materialized_path='/test/folder/',
        )
        subfolder.save()
        payload = {
            'provider': file_node.provider,
            'metadata': {
                'path': '/test/',
                'materialized': '/test/'
            }
        }
        views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload)
        assert_false(GithubFileNode.load(subfolder._id))
        assert_true(TrashedFileNode.load(file_node._id))

    @mock.patch('website.archiver.tasks.archive')
    def test_archived_from_url(self, mock_archive):
        file_node = self.get_test_file()
        second_file_node = self.get_second_test_file()
        file_node.copied_from = second_file_node

        registered_node = self.project.register_node(
            schema=get_default_metaschema(),
            auth=Auth(self.user),
            data=None,
        )

        archived_from_url = views.get_archived_from_url(registered_node, file_node)
        view_url = self.project.web_url_for('addon_view_or_download_file', provider=file_node.provider, path=file_node.copied_from._id)
        assert_true(archived_from_url)
        assert_urls_equal(archived_from_url, view_url)

    @mock.patch('website.archiver.tasks.archive')
    def test_archived_from_url_without_copied_from(self, mock_archive):
        file_node = self.get_test_file()

        registered_node = self.project.register_node(
            schema=get_default_metaschema(),
            auth=Auth(self.user),
            data=None,
        )
        archived_from_url = views.get_archived_from_url(registered_node, file_node)
        assert_false(archived_from_url)

    @mock.patch('website.archiver.tasks.archive')
    def test_copied_from_id_trashed(self, mock_archive):
        file_node = self.get_test_file()
        second_file_node = self.get_second_test_file()
        file_node.copied_from = second_file_node
        self.project.register_node(
            schema=get_default_metaschema(),
            auth=Auth(self.user),
            data=None,
        )
        trashed_node = second_file_node.delete()
        assert_false(trashed_node.copied_from)

    @mock.patch('website.archiver.tasks.archive')
    def test_missing_modified_date_in_file_data(self, mock_archive):
        file_node = self.get_test_file()
        file_data = {
            'name': 'Test File Update',
            'materialized': file_node.materialized_path,
            'modified': None
        }
        file_node.update(revision=None, data=file_data)
        assert_equal(len(file_node.history), 1)
        assert_equal(file_node.history[0], file_data)

    @mock.patch('website.archiver.tasks.archive')
    def test_missing_modified_date_in_file_history(self, mock_archive):
        file_node = self.get_test_file()
        file_node.history.append({'modified': None})
        file_data = {
            'name': 'Test File Update',
            'materialized': file_node.materialized_path,
            'modified': None
        }
        file_node.update(revision=None, data=file_data)
        assert_equal(len(file_node.history), 2)
        assert_equal(file_node.history[1], file_data)

    @with_sentry
    @mock.patch('framework.sentry.sentry.captureMessage')
    def test_update_logs_to_sentry_when_called_with_disordered_metadata(self, mock_capture):
        file_node = self.get_test_file()
        file_node.history.append({'modified': parse_date(
                '2017-08-22T13:54:32.100900',
                ignoretz=True,
                default=timezone.now()  # Just incase nothing can be parsed
            )})
        data = {
            'name': 'a name',
            'materialized': 'materialized',
            'modified': '2016-08-22T13:54:32.100900'
        }
        file_node.update(revision=None, user=None, data=data)
        mock_capture.assert_called_with(unicode('update() receives metatdata older than the newest entry in file history.'), extra={'session': {}})
Пример #52
0
class TestAddonCount(OsfTestCase):
    def setUp(self):
        super(TestAddonCount, self).setUp()
        self.user = AuthUserFactory()
        self.node = ProjectFactory(creator=self.user)
        self.user.add_addon('github')
        self.user_addon = self.user.get_addon('github')

        self.external_account = GitHubAccountFactory(display_name='hmoco1')

        self.user_settings = self.user.get_or_add_addon('github')

        self.user_settings.save()
        self.user.external_accounts.add(self.external_account)
        self.user.save()
        self.node.add_addon('github', Auth(self.user))
        self.node_addon = self.node.get_addon('github')
        self.node_addon.user = self.user.fullname
        self.node_addon.repo = '29 #Strafford APTS'
        self.node_addon.user_settings = self.user_addon
        self.node_addon.external_account = self.external_account
        self.node_addon.save()

        self.user_settings.grant_oauth_access(
            node=self.node,
            external_account=self.external_account,
        )

    def test_run_for_all_addon(self):
        results = AddonSnapshot().get_events()
        names = [res['provider']['name'] for res in results]
        for addon in ADDONS_AVAILABLE:
            assert_in(addon.short_name, names)

    def test_one_user_one_node_one_addon(self):
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['users']['enabled'], 1)
        assert_equal(github_res['nodes']['total'], 1)

    def test_one_user_one_node_one_addon_one_node_linked(self):
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['users']['enabled'], 1)
        assert_equal(github_res['nodes']['total'], 1)

    def test_one_user_with_multiple_githubs(self):
        oauth_settings2 = GitHubAccountFactory(display_name='hmoco2')
        oauth_settings2.save()
        self.user.external_accounts.add(oauth_settings2)
        self.user.save()
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['users']['enabled'], 1)

    def test_one_user_with_multiple_addons(self):
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        googledrive_res = [
            res for res in results if res['provider']['name'] == 'googledrive'
        ][0]
        assert_equal(github_res['users']['enabled'], 1)
        assert_equal(googledrive_res['users']['enabled'], 0)

        self.user.add_addon('googledrive')
        oauth_settings = GoogleDriveAccountFactory()
        oauth_settings.save()
        self.user.external_accounts.add(oauth_settings)
        self.user.save()
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        googledrive_res = [
            res for res in results if res['provider']['name'] == 'googledrive'
        ][0]
        assert_equal(github_res['users']['enabled'], 1)
        assert_equal(googledrive_res['users']['enabled'], 1)

    def test_many_users_each_with_a_different_github(self):
        user = AuthUserFactory()
        user.add_addon('github')
        oauth_settings2 = GitHubAccountFactory(display_name='hmoco2')
        oauth_settings2.save()
        user.external_accounts.add(oauth_settings2)
        user.save()
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['users']['enabled'], 2)
        assert_equal(github_res['users']['authorized'], 1)
        assert_equal(github_res['users']['linked'], 1)

    def test_many_users_each_with_the_same_github_enabled(self):
        user = AuthUserFactory()
        user.add_addon('github')
        user.external_accounts.add(self.external_account)
        user.save()
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['users']['enabled'], 2)

    def test_github_enabled_not_linked_or_authorized(self):
        user = AuthUserFactory()
        user.add_addon('github')
        user.external_accounts.add(self.external_account)
        user.save()
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['users']['enabled'], 2)
        assert_equal(github_res['users']['authorized'], 1)
        assert_equal(github_res['users']['linked'], 1)

    def test_one_node_with_multiple_addons(self):
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        googledrive_res = [
            res for res in results if res['provider']['name'] == 'googledrive'
        ][0]
        assert_equal(github_res['nodes']['total'], 1)
        assert_equal(googledrive_res['nodes']['total'], 0)

        self.user.add_addon('googledrive')
        user_addon = self.user.get_addon('googledrive')
        oauth_settings = GoogleDriveAccountFactory()
        oauth_settings.save()
        self.user.external_accounts.add(oauth_settings)
        self.user.save()
        self.node.add_addon('googledrive', Auth(self.user))
        node_addon = self.node.get_addon('googledrive')
        node_addon.user = self.user.fullname
        node_addon.user_settings = user_addon
        node_addon.external_account = oauth_settings
        node_addon.save()
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        googledrive_res = [
            res for res in results if res['provider']['name'] == 'googledrive'
        ][0]
        assert_equal(github_res['nodes']['total'], 1)
        assert_equal(googledrive_res['nodes']['total'], 1)

    def test_many_nodes_with_one_addon(self):
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['nodes']['total'], 1)

        node = ProjectFactory(creator=self.user)
        node.add_addon('github', Auth(self.user))
        node_addon = node.get_addon('github')
        node_addon.user = self.user.fullname
        node_addon.repo = '8 (circle)'
        node_addon.user_settings = self.user_addon
        node_addon.external_account = self.external_account
        node_addon.save()
        node.save()

        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['nodes']['total'], 2)

    def test_node_count_deleted_addon(self):
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['nodes']['deleted'], 0)

        node = ProjectFactory(creator=self.user)
        node.add_addon('github', Auth(self.user))
        node_addon = node.get_addon('github')
        node_addon.delete()

        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['nodes']['deleted'], 1)

    def test_node_count_disconected_addon(self):
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['nodes']['disconnected'], 0)

        node = ProjectFactory(creator=self.user)
        node.add_addon('github', Auth(self.user))
        node_addon = node.get_addon('github')
        node_addon.external_account = None
        node_addon.save()

        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['nodes']['disconnected'], 1)

    def test_all_users_have_wiki_osfstorage_enabled(self):
        all_user_count = OSFUser.objects.all().count()
        results = AddonSnapshot().get_events()
        osfstorage_res = [
            res for res in results if res['provider']['name'] == 'osfstorage'
        ][0]
        wiki_res = [
            res for res in results if res['provider']['name'] == 'osfstorage'
        ][0]

        assert_equal(osfstorage_res['users']['enabled'], all_user_count)
        assert_equal(wiki_res['users']['enabled'], all_user_count)

    def test_wiki_deleted_shows_as_deleted(self):
        node = ProjectFactory(creator=self.user)
        node.delete_addon('wiki', auth=Auth(self.user))

        results = AddonSnapshot().get_events()
        wiki_res = [
            res for res in results if res['provider']['name'] == 'wiki'
        ][0]

        assert_equal(wiki_res['nodes']['deleted'], 1)

    def test_node_settings_has_no_owner_not_connected(self):
        self.node_addon.owner = None
        self.node_addon.save()

        results = AddonSnapshot().get_events()
        storage_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(storage_res['nodes']['connected'], 0)