Example #1
0
class TestViews(OsfTestCase):
    def setUp(self):
        super(TestViews, self).setUp()
        self.user = AuthUserFactory()
        self.user_addon = self.user.get_or_add_addon('twofactor')
        self.user_settings = self.user.get_addon('twofactor')

    def test_confirm_code(self):
        # Send a valid code to the API endpoint for the user settings.
        url = api_url_for('twofactor_settings_put')
        res = self.app.put_json(
            url, {'code': _valid_code(self.user_settings.totp_secret)},
            auth=self.user.auth)

        # reload the user settings object from the DB
        self.user_settings.reload()

        assert_true(self.user_settings.is_confirmed)
        assert_equal(res.status_code, 200)

    def test_confirm_code_failure(self):
        url = api_url_for('twofactor_settings_put')
        res = self.app.put_json(url, {'code': '0000000'},
                                auth=self.user.auth,
                                expect_errors=True)
        assert_equal(res.status_code, 403)
        json = res.json
        assert_in('verification code', json['message_long'])

        # reload the user settings object from the DB
        self.user_settings.reload()

        assert_false(self.user_settings.is_confirmed)
Example #2
0
class TestUtils(OsfTestCase):
    @mock.patch('website.addons.twofactor.models.push_status_message')
    def setUp(self, mocked):
        super(TestUtils, self).setUp()
        self.user = AuthUserFactory()
        self.user_addon = self.user.get_or_add_addon('twofactor')
        self.user_settings = self.user.get_addon('twofactor')

    def test_serialize_urls_enabled(self):
        urls = serialize_urls(self.user_addon)
        for key in ['enable', 'disable', 'settings', 'otpauth']:
            assert_in(key, urls)
        assert_equal(urls['otpauth'], self.user_addon.otpauth_url)

    def test_serialize_urls_disabled(self):
        urls = serialize_urls(None)
        for key in ['enable', 'disable', 'settings', 'otpauth']:
            assert_in(key, urls)
        assert_equal(urls['otpauth'], '')

    def test_serialize_settings_enabled_and_unconfirmed(self):
        settings = serialize_settings(Auth(self.user))
        assert_true(settings['is_enabled'])
        assert_false(settings['is_confirmed'])
        assert_equal(settings['secret'], self.user_addon.totp_secret_b32)
        assert_equal(settings['drift'], self.user_addon.totp_drift)

    def test_serialize_settings_enabled_and_confirmed(self):
        self.user_addon.is_confirmed = True
        self.user_addon.save()
        settings = serialize_settings(Auth(self.user))
        assert_true(settings['is_enabled'])
        assert_true(settings['is_confirmed'])
        assert_equal(settings['secret'], self.user_addon.totp_secret_b32)
        assert_equal(settings['drift'], self.user_addon.totp_drift)

    def test_serialize_settings_disabled(self):
        user = AuthUserFactory()
        settings = serialize_settings(Auth(user))
        assert_false(settings['is_enabled'])
        assert_false(settings['is_confirmed'])
        assert_equal(settings['secret'], None)
        assert_equal(settings['drift'], None)
Example #3
0
class TestUtils(OsfTestCase):
    @mock.patch('website.addons.twofactor.models.push_status_message')
    def setUp(self, mocked):
        super(TestUtils, self).setUp()
        self.user = AuthUserFactory()
        self.user_addon = self.user.get_or_add_addon('twofactor')
        self.user_settings = self.user.get_addon('twofactor')

    def test_serialize_urls_enabled(self):
        urls = serialize_urls(self.user_addon)
        for key in ['enable', 'disable', 'settings', 'otpauth']:
            assert_in(key, urls)
        assert_equal(urls['otpauth'], self.user_addon.otpauth_url)

    def test_serialize_urls_disabled(self):
        urls = serialize_urls(None)
        for key in ['enable', 'disable', 'settings', 'otpauth']:
            assert_in(key, urls)
        assert_equal(urls['otpauth'], '')

    def test_serialize_settings_enabled_and_unconfirmed(self):
        settings = serialize_settings(Auth(self.user))
        assert_true(settings['is_enabled'])
        assert_false(settings['is_confirmed'])
        assert_equal(settings['secret'], self.user_addon.totp_secret_b32)
        assert_equal(settings['drift'], self.user_addon.totp_drift)

    def test_serialize_settings_enabled_and_confirmed(self):
        self.user_addon.is_confirmed = True
        self.user_addon.save()
        settings = serialize_settings(Auth(self.user))
        assert_true(settings['is_enabled'])
        assert_true(settings['is_confirmed'])
        assert_equal(settings['secret'], self.user_addon.totp_secret_b32)
        assert_equal(settings['drift'], self.user_addon.totp_drift)

    def test_serialize_settings_disabled(self):
        user = AuthUserFactory()
        settings = serialize_settings(Auth(user))
        assert_false(settings['is_enabled'])
        assert_false(settings['is_confirmed'])
        assert_equal(settings['secret'], None)
        assert_equal(settings['drift'], None)
Example #4
0
class TestGoogleDriveHgridViews(OsfTestCase):
    def setUp(self):
        super(TestGoogleDriveHgridViews, self).setUp()
        self.account = GoogleDriveAccountFactory()
        self.user = AuthUserFactory(external_accounts=[self.account])
        self.user_settings = self.user.get_or_add_addon('googledrive')
        self.project = ProjectFactory(creator=self.user)
        self.project.add_addon('googledrive', Auth(self.user))
        self.node_settings = self.project.get_addon('googledrive')
        self.node_settings.user_settings = self.user_settings
        self.user_settings.save()
        self.node_settings.save()
        # Log user in
        self.app.authenticate(*self.user.auth)

    @mock.patch.object(GoogleDriveClient, 'folders')
    def test_googledrive_folders(self, mock_drive_client_folders):
        folderId = '12345'
        self.node_settings.set_auth(external_account=self.account,
                                    user=self.user)
        self.node_settings.save()
        mock_drive_client_folders.return_value = sample_folder_data['items']
        url = self.project.api_url_for('googledrive_folders',
                                       folderId=folderId)
        res = self.app.get(url)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json), len(sample_folder_data['items']))

    @mock.patch(
        'website.addons.googledrive.views.hgrid.GoogleDriveClient.about')
    def test_googledrive_folders_returns_only_root(self, mock_about):
        mock_about.return_value = {'rootFolderId': '24601'}
        self.node_settings.set_auth(external_account=self.account,
                                    user=self.user)
        self.node_settings.save()
        url = self.project.api_url_for('googledrive_folders')
        res = self.app.get(url, auth=self.user.auth)

        assert_equal(len(res.json), 1)
        assert_equal(res.status_code, 200)
        assert_equal(res.json[0]['id'], '24601')
Example #5
0
class TestViews(OsfTestCase):
    @mock.patch('website.addons.twofactor.models.push_status_message')
    def setUp(self, mocked):
        super(TestViews, self).setUp()
        self.user = AuthUserFactory()
        self.user_addon = self.user.get_or_add_addon('twofactor')
        self.user_settings = self.user.get_addon('twofactor')

    def test_confirm_code(self):
        # Send a valid code to the API endpoint for the user settings.
        url = api_url_for('twofactor_settings_put')
        res = self.app.put_json(
            url,
            {'code': _valid_code(self.user_settings.totp_secret)},
            auth=self.user.auth
        )

        # reload the user settings object from the DB
        self.user_settings.reload()

        assert_true(self.user_settings.is_confirmed)
        assert_equal(res.status_code, 200)

    def test_confirm_code_failure(self):
        url = api_url_for('twofactor_settings_put')
        res = self.app.put_json(
            url,
            {'code': '0000000'},
            auth=self.user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 403)
        json = res.json
        assert_in('verification code', json['message_long'])

        # reload the user settings object from the DB
        self.user_settings.reload()

        assert_false(self.user_settings.is_confirmed)
Example #6
0
class TestRemove2Factor(AdminTestCase):
    def setUp(self):
        super(TestRemove2Factor, self).setUp()
        self.user = AuthUserFactory()

    @mock.patch('admin.users.views.User.delete_addon')
    def test_remove_two_factor_get(self, mock_delete_addon):
        guid = self.user._id
        request = RequestFactory().get('/fake_path')
        remove_2_factor(request, guid)
        mock_delete_addon.assert_called_with('twofactor')

    def test_integration_delete_two_factor(self):
        guid = self.user._id
        user_addon = self.user.get_or_add_addon('twofactor')
        assert_not_equal(user_addon, None)
        user_settings = self.user.get_addon('twofactor')
        assert_not_equal(user_settings, None)
        request = RequestFactory().post('/fake_path')
        remove_2_factor(request, guid)
        post_addon = self.user.get_addon('twofactor')
        assert_equal(post_addon, None)
Example #7
0
class TestRemove2Factor(AdminTestCase):
    def setUp(self):
        super(TestRemove2Factor, self).setUp()
        self.user = AuthUserFactory()

    @mock.patch('admin.users.views.User.delete_addon')
    def test_remove_two_factor_get(self, mock_delete_addon):
        guid = self.user._id
        request = RequestFactory().get('/fake_path')
        remove_2_factor(request, guid)
        mock_delete_addon.assert_called_with('twofactor')

    def test_integration_delete_two_factor(self):
        guid = self.user._id
        user_addon = self.user.get_or_add_addon('twofactor')
        assert_not_equal(user_addon, None)
        user_settings = self.user.get_addon('twofactor')
        assert_not_equal(user_settings, None)
        request = RequestFactory().post('/fake_path')
        remove_2_factor(request, guid)
        post_addon = self.user.get_addon('twofactor')
        assert_equal(post_addon, None)
Example #8
0
class TestGoogleDriveHgridViews(OsfTestCase):

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

    @mock.patch.object(GoogleDriveClient, 'folders')
    def test_googledrive_folders(self, mock_drive_client_folders):
        folderId = '12345'
        self.node_settings.set_auth(external_account=self.account, user=self.user)
        self.node_settings.save()
        mock_drive_client_folders.return_value = sample_folder_data['items']
        url = self.project.api_url_for('googledrive_folders', folderId=folderId)
        res = self.app.get(url)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json), len(sample_folder_data['items']))

    @mock.patch('website.addons.googledrive.views.hgrid.GoogleDriveClient.about')
    def test_googledrive_folders_returns_only_root(self, mock_about):
        mock_about.return_value = {'rootFolderId': '24601'}
        self.node_settings.set_auth(external_account=self.account, user=self.user)
        self.node_settings.save()
        url = self.project.api_url_for('googledrive_folders')
        res = self.app.get(url, auth=self.user.auth)

        assert_equal(len(res.json), 1)
        assert_equal(res.status_code, 200)
        assert_equal(res.json[0]['id'], '24601')
Example #9
0
class TestRemove2Factor(AdminTestCase):
    def setUp(self):
        super(TestRemove2Factor, self).setUp()
        self.user = AuthUserFactory()
        self.request = RequestFactory().post('/fake_path')
        self.view = User2FactorDeleteView()
        self.view = setup_log_view(self.view, self.request, guid=self.user._id)

    @mock.patch('admin.users.views.User.delete_addon')
    def test_remove_two_factor_get(self, mock_delete_addon):
        self.view.delete(self.request)
        mock_delete_addon.assert_called_with('twofactor')

    def test_integration_delete_two_factor(self):
        user_addon = self.user.get_or_add_addon('twofactor')
        nt.assert_not_equal(user_addon, None)
        user_settings = self.user.get_addon('twofactor')
        nt.assert_not_equal(user_settings, None)
        count = OSFLogEntry.objects.count()
        self.view.delete(self.request)
        post_addon = self.user.get_addon('twofactor')
        nt.assert_equal(post_addon, None)
        nt.assert_equal(OSFLogEntry.objects.count(), count + 1)
Example #10
0
class TestRemove2Factor(AdminTestCase):
    def setUp(self):
        super(TestRemove2Factor, self).setUp()
        self.user = AuthUserFactory()
        self.request = RequestFactory().post('/fake_path')
        self.view = User2FactorDeleteView()
        self.view = setup_log_view(self.view, self.request, guid=self.user._id)

    @mock.patch('admin.users.views.User.delete_addon')
    def test_remove_two_factor_get(self, mock_delete_addon):
        self.view.delete(self.request)
        mock_delete_addon.assert_called_with('twofactor')

    def test_integration_delete_two_factor(self):
        user_addon = self.user.get_or_add_addon('twofactor')
        nt.assert_not_equal(user_addon, None)
        user_settings = self.user.get_addon('twofactor')
        nt.assert_not_equal(user_settings, None)
        count = OSFLogEntry.objects.count()
        self.view.delete(self.request)
        post_addon = self.user.get_addon('twofactor')
        nt.assert_equal(post_addon, None)
        nt.assert_equal(OSFLogEntry.objects.count(), count + 1)
Example #11
0
class TestUserSettings(OsfTestCase):

    ADDONS_UNDER_TEST = {
        MockOAuth2Provider.short_name: {
            'user_settings': MockUserSettings,
            'node_settings': MockNodeSettings,
        }
    }

    @classmethod
    def setUpClass(cls):
        super(TestUserSettings, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        super(TestUserSettings, cls).tearDownClass()

    def setUp(self):
        super(TestUserSettings, self).setUp()
        self.user = AuthUserFactory()

        self.user_settings = self.user.get_or_add_addon(
            MockUserSettings.oauth_provider.short_name
        )

        self.external_account = ExternalAccountFactory()
        self.user.external_accounts.append(self.external_account)
        self.user.save()

        self.project = ProjectFactory(creator=self.user)

    def tearDown(self):
        super(TestUserSettings, self).tearDown()

    def test_connected_accounts_empty(self):
        self.user.external_accounts = []

        assert_equal(
            self.user_settings.external_accounts,
            []
        )

    def test_connected_accounts(self):
        assert_equal(
            self.user_settings.external_accounts,
            [self.external_account]
        )

    def test_verify_false_no_grants(self):
        assert_false(
            self.user_settings.verify_oauth_access(
                external_account=self.external_account,
                node=self.project
            )
        )

    def test_verify_false_with_grants(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account,
            node=ProjectFactory()
        )

        assert_false(
            self.user_settings.verify_oauth_access(
                external_account=self.external_account,
                node=self.project
            )
        )

    def test_verify_false_metadata(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account,
            node=self.project,
            metadata={'foo': 'bar'}
        )

        assert_false(
            self.user_settings.verify_oauth_access(
                external_account=self.external_account,
                node=self.project,
                metadata={'baz': 'qiz'}
            )
        )

    def test_verify_true(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account,
            node=self.project
        )

        assert_true(
            self.user_settings.verify_oauth_access(
                external_account=self.external_account,
                node=self.project
            )
        )

    def test_verify_true_with_metadata(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account,
            node=self.project,
            metadata={'foo': 'bar'}
        )

        assert_true(
            self.user_settings.verify_oauth_access(
                external_account=self.external_account,
                node=self.project,
                metadata={'foo': 'bar'}
            )
        )

    def test_grant(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account,
            node=self.project
        )

        assert_equal(
            self.user_settings.oauth_grants,
            {
                self.project._id: {
                    self.external_account._id: {}
                }
            }
        )

    def test_grant_not_owned(self):
        self.user.external_accounts = []

        with assert_raises(PermissionsError):
            self.user_settings.grant_oauth_access(
                external_account=self.external_account,
                node=self.project
            )

        assert_equal(
            self.user_settings.oauth_grants,
            {}
        )

    def test_grant_metadata(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account,
            node=self.project,
            metadata={'foo': 'bar'}
        )

        assert_equal(
            self.user_settings.oauth_grants,
            {
                self.project._id: {
                    self.external_account._id: {'foo': 'bar'}
                }
            }
        )

    def test_on_delete(self):
        node_settings = self.project.get_or_add_addon(
            MockUserSettings.oauth_provider.short_name,
            auth=Auth(user=self.user)
        )

        node_settings.set_auth(
            external_account=self.external_account,
            user=self.user
        )

        self.user.delete_addon(
            MockUserSettings.oauth_provider.short_name
        )

        node_settings.reload()

        assert_is_none(node_settings.external_account)
        assert_is_none(node_settings.user_settings)
Example #12
0
class TestUserSettings(OsfTestCase):

    ADDONS_UNDER_TEST = {
        MockOAuth2Provider.short_name: {
            'user_settings': MockUserSettings,
            'node_settings': MockNodeSettings,
        }
    }

    @classmethod
    def setUpClass(cls):
        super(TestUserSettings, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        super(TestUserSettings, cls).tearDownClass()

    def setUp(self):
        super(TestUserSettings, self).setUp()
        self.user = AuthUserFactory()

        self.user_settings = self.user.get_or_add_addon(
            MockUserSettings.oauth_provider.short_name)

        self.external_account = ExternalAccountFactory()
        self.user.external_accounts.append(self.external_account)
        self.user.save()

        self.project = ProjectFactory(creator=self.user)

    def tearDown(self):
        super(TestUserSettings, self).tearDown()

    def test_connected_accounts_empty(self):
        self.user.external_accounts = []

        assert_equal(self.user_settings.external_accounts, [])

    def test_connected_accounts(self):
        assert_equal(self.user_settings.external_accounts,
                     [self.external_account])

    def test_verify_false_no_grants(self):
        assert_false(
            self.user_settings.verify_oauth_access(
                external_account=self.external_account, node=self.project))

    def test_verify_false_with_grants(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account, node=ProjectFactory())

        assert_false(
            self.user_settings.verify_oauth_access(
                external_account=self.external_account, node=self.project))

    def test_verify_false_metadata(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account,
            node=self.project,
            metadata={'foo': 'bar'})

        assert_false(
            self.user_settings.verify_oauth_access(
                external_account=self.external_account,
                node=self.project,
                metadata={'baz': 'qiz'}))

    def test_verify_true(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account, node=self.project)

        assert_true(
            self.user_settings.verify_oauth_access(
                external_account=self.external_account, node=self.project))

    def test_verify_true_with_metadata(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account,
            node=self.project,
            metadata={'foo': 'bar'})

        assert_true(
            self.user_settings.verify_oauth_access(
                external_account=self.external_account,
                node=self.project,
                metadata={'foo': 'bar'}))

    def test_grant(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account, node=self.project)

        assert_equal(self.user_settings.oauth_grants,
                     {self.project._id: {
                         self.external_account._id: {}
                     }})

    def test_grant_not_owned(self):
        self.user.external_accounts = []

        with assert_raises(PermissionsError):
            self.user_settings.grant_oauth_access(
                external_account=self.external_account, node=self.project)

        assert_equal(self.user_settings.oauth_grants, {})

    def test_grant_metadata(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account,
            node=self.project,
            metadata={'foo': 'bar'})

        assert_equal(
            self.user_settings.oauth_grants,
            {self.project._id: {
                self.external_account._id: {
                    'foo': 'bar'
                }
            }})

    @mock.patch(
        'tests.test_addons_oauth.MockUserSettings.revoke_remote_oauth_access')
    @mock.patch('framework.auth.core._get_current_user')
    def test_revoke_remote_access_called(self, mock_decorator, mock_revoke):
        mock_decorator.return_value = self.user
        self.user_settings.delete()
        assert_equal(mock_revoke.call_count, 1)

    @mock.patch(
        'tests.test_addons_oauth.MockUserSettings.revoke_remote_oauth_access')
    @mock.patch('framework.auth.core._get_current_user')
    def test_revoke_remote_access_not_called(self, mock_decorator,
                                             mock_revoke):
        mock_decorator.return_value = self.user
        user2 = AuthUserFactory()
        user2.external_accounts.append(self.external_account)
        user2.save()
        self.user_settings.delete()
        assert_equal(mock_revoke.call_count, 0)

    def test_on_delete(self):
        node_settings = self.project.get_or_add_addon(
            MockUserSettings.oauth_provider.short_name,
            auth=Auth(user=self.user))

        node_settings.set_auth(external_account=self.external_account,
                               user=self.user)

        self.user.delete_addon(MockUserSettings.oauth_provider.short_name)

        node_settings.reload()

        assert_is_none(node_settings.external_account)
        assert_is_none(node_settings.user_settings)
Example #13
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.append(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 tearDown(self):
        GitHubNodeSettings.remove()
        GitHubUserSettings.remove()
        GoogleDriveNodeSettings.remove()
        GoogleDriveUserSettings.remove()

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

    def test_one_user_one_node_one_addon(self):
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res["provider"]["name"] == "github"][0]
        assert_equal(github_res["users"]["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.append(oauth_settings2)
        self.user.save()
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res["provider"]["name"] == "github"][0]
        assert_equal(github_res["users"]["enabled"], 1)

    def test_one_user_with_multiple_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.append(oauth_settings)
        self.user.save()
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res["provider"]["name"] == "github"][0]
        googledrive_res = [res for res in results if res["provider"]["name"] == "googledrive"][0]
        assert_equal(github_res["users"]["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.append(oauth_settings2)
        user.save()
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res["provider"]["name"] == "github"][0]
        assert_equal(github_res["users"]["enabled"], 2)
        assert_equal(github_res["users"]["authorized"], 1)
        assert_equal(github_res["users"]["linked"], 1)

    def test_many_users_each_with_the_same_github_enabled(self):
        user = AuthUserFactory()
        user.add_addon("github")
        user.external_accounts.append(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.append(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.append(oauth_settings)
        self.user.save()
        self.node.add_addon("googledrive", Auth(self.user))
        node_addon = self.node.get_addon("googledrive")
        node_addon.user = self.user.fullname
        node_addon.user_settings = user_addon
        node_addon.external_account = oauth_settings
        node_addon.save()
        results = AddonSnapshot().get_events()
        github_res = [res for res in results if res["provider"]["name"] == "github"][0]
        googledrive_res = [res for res in results if res["provider"]["name"] == "googledrive"][0]
        assert_equal(github_res["nodes"]["total"], 1)
        assert_equal(googledrive_res["nodes"]["total"], 1)

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

        node = ProjectFactory(creator=self.user)
        node.add_addon("github", Auth(self.user))
        node_addon = node.get_addon("github")
        node_addon.user = self.user.fullname
        node_addon.repo = "8 (circle)"
        node_addon.user_settings = self.user_addon
        node_addon.external_account = self.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 = User.find().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)

    def test_bookmark_collection_not_counted(self):
        BookmarkCollectionFactory(creator=self.user)
        all_node_count = Node.find().count()

        results = AddonSnapshot().get_events()
        storage_res = [res for res in results if res["provider"]["name"] == "osfstorage"][0]
        assert_equal(storage_res["nodes"]["connected"], all_node_count - 1)
Example #14
0
class ApiAddonTestCase(ApiTestCase):
    """Base `TestCase` for tests that require interaction with addons.

    """

    @abc.abstractproperty
    def short_name(self):
        pass

    @abc.abstractproperty
    def addon_type(self):
        pass

    @abc.abstractmethod
    def _apply_auth_configuration(self):
        pass

    @abc.abstractmethod
    def _set_urls(self):
        pass

    def _settings_kwargs(self, node, user_settings):
        return {"user_settings": self.user_settings, "folder_id": "1234567890", "owner": self.node}

    def setUp(self):
        super(ApiAddonTestCase, self).setUp()
        from tests.factories import ProjectFactory, AuthUserFactory
        from website.addons.base import (
            AddonOAuthNodeSettingsBase,
            AddonNodeSettingsBase,
            AddonOAuthUserSettingsBase,
            AddonUserSettingsBase,
        )

        assert self.addon_type in ("CONFIGURABLE", "OAUTH", "UNMANAGEABLE", "INVALID")
        self.account = None
        self.node_settings = None
        self.user_settings = None
        self.user = AuthUserFactory()
        self.auth = Auth(self.user)
        self.node = ProjectFactory(creator=self.user)

        if self.addon_type not in ("UNMANAGEABLE", "INVALID"):
            if self.addon_type in ("OAUTH", "CONFIGURABLE"):
                self.account = self.AccountFactory()
                self.user.external_accounts.append(self.account)
                self.user.save()

            self.user_settings = self.user.get_or_add_addon(self.short_name)
            self.node_settings = self.node.get_or_add_addon(self.short_name, auth=self.auth)

            if self.addon_type in ("OAUTH", "CONFIGURABLE"):
                self.node_settings.set_auth(self.account, self.user)
                self._apply_auth_configuration()

        if self.addon_type in ("OAUTH", "CONFIGURABLE"):
            assert isinstance(self.node_settings, AddonOAuthNodeSettingsBase)
            assert isinstance(self.user_settings, AddonOAuthUserSettingsBase)

        self.account_id = self.account._id if self.account else None
        self.set_urls()

    def tearDown(self):
        super(ApiAddonTestCase, self).tearDown()
        self.user.remove()
        self.node.remove()
        if self.node_settings:
            self.node_settings.remove()
        if self.user_settings:
            self.user_settings.remove()
        if self.account:
            self.account.remove()
Example #15
0
class TestGoogleDriveConfigViews(OsfTestCase):

    def setUp(self):
        super(TestGoogleDriveConfigViews, self).setUp()
        self.account = GoogleDriveAccountFactory()
        self.user = AuthUserFactory(external_accounts=[self.account])
        self.user_settings = self.user.get_or_add_addon('googledrive')
        self.project = ProjectFactory(creator=self.user)
        self.project.add_addon('googledrive', Auth(self.user))
        self.node_settings = self.project.get_addon('googledrive')
        self.node_settings.user_settings = self.user_settings
        self.node_settings.save()
        self.user_settings.save()
        # Log user in
        self.app.authenticate(*self.user.auth)

    def test_list_googledrive_accounts_returns_accounts_single(self):
        url = api_url_for('list_googledrive_user_accounts')
        res = self.app.get(url)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['accounts']), 1)
        assert_equal(res.json['accounts'][0]['provider_id'], self.account.provider_id)
        assert_equal(res.json['accounts'][0]['provider_name'], self.account.provider_name)

    def test_list_googledrive_accounts_returns_accounts_multiple(self):
        external_account = GoogleDriveAccountFactory()
        self.user.external_accounts.append(external_account) # self.account is already present
        self.user.save()
        url = api_url_for('list_googledrive_user_accounts')
        res = self.app.get(url)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['accounts']), 2)

    def test_googledrive_config_get_return_correct_urls(self):
        url = self.project.api_url_for('googledrive_config_get')
        res = self.app.get(url)
        result = res.json['result']
        assert_equal(result['urls']['accounts'],  self.project.api_url_for('list_googledrive_user_accounts'))
        assert_equal(result['urls']['auth'], api_url_for('oauth_connect', service_name='googledrive'))
        assert_equal(result['urls']['config'],  self.project.api_url_for('googledrive_config_put'))
        assert_equal(result['urls']['deauthorize'],  self.project.api_url_for('googledrive_remove_user_auth'))
        assert_equal(result['urls']['files'],  self.project.web_url_for('collect_file_trees'))
        assert_equal(result['urls']['folders'],  self.project.api_url_for('googledrive_folders'))
        assert_equal(result['urls']['importAuth'],  self.project.api_url_for('googledrive_import_user_auth'))
        assert_equal(result['urls']['settings'],  web_url_for('user_addons'))

    def test_googledrive_config_get_has_auth(self):
        self.node_settings.set_auth(external_account=self.account, user=self.user)
        self.node_settings.save()
        url = self.project.api_url_for('googledrive_config_get')
        res = self.app.get(url)
        assert_equal(res.status_code, 200)
        result = res.json['result']
        assert_true(result['nodeHasAuth'])

    def test_googledrive_config_get_does_not_has_auth(self):
        url = self.project.api_url_for('googledrive_config_get')
        res = self.app.get(url)
        result = res.json['result']
        assert_false(result['nodeHasAuth'])

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

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

        # Folder was set
        assert_equal(self.node_settings.folder_path, 'Google Drive/ My Folder')
        # A log event was created
        last_log = self.project.logs[-1]
        assert_equal(last_log.action, 'googledrive_folder_selected')
        params = last_log.params
        assert_equal(params['folder'], ' My Folder')

    def test_googledrive_import_user_auth(self):
        url = self.project.api_url_for('googledrive_import_user_auth', auth=self.user.auth)
        self.app.put_json(url, {'external_account_id': self.account._id})
        self.node_settings.reload()
        assert_equal(self.node_settings.external_account, self.account)

    def test_googledrive_remove_user_auth(self):
        self.node_settings.set_auth(external_account=self.account, user=self.user)
        self.node_settings.save()
        assert_equal(self.node_settings.external_account, self.account)
        url = self.project.api_url_for('googledrive_remove_user_auth', auth=self.user.auth)
        self.app.delete(url)
        self.node_settings.reload()
        assert_equal(self.node_settings.external_account, None)
Example #16
0
class TestBasicAuthenticationValidation(ApiTestCase):
    """Test that APIv2 requests can validate and respond to Basic Authentication"""

    TOTP_SECRET = "b8f85986068f8079aa9d"

    def setUp(self):
        super(TestBasicAuthenticationValidation, self).setUp()
        self.user1 = AuthUserFactory()
        self.user2 = AuthUserFactory()

        # Test projects for which a given user DOES and DOES NOT  have appropriate permissions
        self.reachable_project = ProjectFactory(title="Private Project User 1", is_public=False, creator=self.user1)
        self.unreachable_project = ProjectFactory(title="Private Project User 2", is_public=False, creator=self.user2)
        self.reachable_url = "/{}nodes/{}/".format(API_BASE, self.reachable_project._id)
        self.unreachable_url = "/{}nodes/{}/".format(API_BASE, self.unreachable_project._id)  # User1 can't access this

    def test_missing_credential_fails(self):
        res = self.app.get(self.unreachable_url, auth=None, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_equal(res.json.get("errors")[0]["detail"], "Authentication credentials were not provided.")

    def test_invalid_credential_fails(self):
        res = self.app.get(self.unreachable_url, auth=(self.user1.username, "invalid password"), expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_equal(res.json.get("errors")[0]["detail"], "Invalid username/password.")

    def test_valid_credential_authenticates_and_has_permissions(self):
        res = self.app.get(self.reachable_url, auth=self.user1.auth)
        assert_equal(res.status_code, 200, msg=res.json)

    def test_valid_credential_authenticates_but_user_lacks_object_permissions(self):
        res = self.app.get(self.unreachable_url, auth=self.user1.auth, expect_errors=True)
        assert_equal(res.status_code, 403, msg=res.json)

    @mock.patch("website.addons.twofactor.models.push_status_message")
    def test_valid_credential_but_twofactor_required(self, mock_push_status_message):
        user1_addon = self.user1.get_or_add_addon("twofactor")
        user1_addon.totp_drift = 1
        user1_addon.totp_secret = self.TOTP_SECRET
        user1_addon.is_confirmed = True
        user1_addon.save()

        res = self.app.get(self.reachable_url, auth=self.user1.auth, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_equal(res.headers["X-OSF-OTP"], "required; app")
        assert_equal(res.json.get("errors")[0]["detail"], "Must specify two-factor authentication OTP code.")

    @mock.patch("website.addons.twofactor.models.push_status_message")
    def test_valid_credential_twofactor_invalid_otp(self, mock_push_status_message):
        user1_addon = self.user1.get_or_add_addon("twofactor")
        user1_addon.totp_drift = 1
        user1_addon.totp_secret = self.TOTP_SECRET
        user1_addon.is_confirmed = True
        user1_addon.save()

        res = self.app.get(
            self.reachable_url, auth=self.user1.auth, headers={"X-OSF-OTP": "invalid otp"}, expect_errors=True
        )
        assert_equal(res.status_code, 401)
        assert_true("X-OSF-OTP" not in res.headers)
        assert_equal(res.json.get("errors")[0]["detail"], "Invalid two-factor authentication OTP code.")

    @mock.patch("website.addons.twofactor.models.push_status_message")
    def test_valid_credential_twofactor_valid_otp(self, mock_push_status_message):
        user1_addon = self.user1.get_or_add_addon("twofactor")
        user1_addon.totp_drift = 1
        user1_addon.totp_secret = self.TOTP_SECRET
        user1_addon.is_confirmed = True
        user1_addon.save()

        res = self.app.get(
            self.reachable_url, auth=self.user1.auth, headers={"X-OSF-OTP": _valid_code(self.TOTP_SECRET)}
        )
        assert_equal(res.status_code, 200)
Example #17
0
class ApiAddonTestCase(ApiTestCase):
    """Base `TestCase` for tests that require interaction with addons.

    """
    @abc.abstractproperty
    def short_name(self):
        pass

    @abc.abstractproperty
    def addon_type(self):
        pass

    @abc.abstractmethod
    def _apply_auth_configuration(self):
        pass

    @abc.abstractmethod
    def _set_urls(self):
        pass

    def _settings_kwargs(self, node, user_settings):
        return {
            'user_settings': self.user_settings,
            'folder_id': '1234567890',
            'owner': self.node
        }

    def setUp(self):
        super(ApiAddonTestCase, self).setUp()
        from tests.factories import (
            ProjectFactory,
            AuthUserFactory,
        )
        from website.addons.base import (AddonOAuthNodeSettingsBase,
                                         AddonNodeSettingsBase,
                                         AddonOAuthUserSettingsBase,
                                         AddonUserSettingsBase)
        assert self.addon_type in ('CONFIGURABLE', 'OAUTH', 'UNMANAGEABLE',
                                   'INVALID')
        self.account = None
        self.node_settings = None
        self.user_settings = None
        self.user = AuthUserFactory()
        self.auth = Auth(self.user)
        self.node = ProjectFactory(creator=self.user)

        if self.addon_type not in ('UNMANAGEABLE', 'INVALID'):
            if self.addon_type in ('OAUTH', 'CONFIGURABLE'):
                self.account = self.AccountFactory()
                self.user.external_accounts.append(self.account)
                self.user.save()

            self.user_settings = self.user.get_or_add_addon(self.short_name)
            self.node_settings = self.node.get_or_add_addon(self.short_name,
                                                            auth=self.auth)

            if self.addon_type in ('OAUTH', 'CONFIGURABLE'):
                self.node_settings.set_auth(self.account, self.user)
                self._apply_auth_configuration()

        if self.addon_type in ('OAUTH', 'CONFIGURABLE'):
            assert isinstance(self.node_settings, AddonOAuthNodeSettingsBase)
            assert isinstance(self.user_settings, AddonOAuthUserSettingsBase)

        self.account_id = self.account._id if self.account else None
        self.set_urls()

    def tearDown(self):
        super(ApiAddonTestCase, self).tearDown()
        self.user.remove()
        self.node.remove()
        if self.node_settings:
            self.node_settings.remove()
        if self.user_settings:
            self.user_settings.remove()
        if self.account:
            self.account.remove()
Example #18
0
class TestBasicAuthenticationValidation(ApiTestCase):
    """Test that APIv2 requests can validate and respond to Basic Authentication"""

    TOTP_SECRET = 'b8f85986068f8079aa9d'

    def setUp(self):
        super(TestBasicAuthenticationValidation, self).setUp()
        self.user1 = AuthUserFactory()
        self.user2 = AuthUserFactory()

        # Test projects for which a given user DOES and DOES NOT  have appropriate permissions
        self.reachable_project = ProjectFactory(title="Private Project User 1",
                                                is_public=False,
                                                creator=self.user1)
        self.unreachable_project = ProjectFactory(
            title="Private Project User 2",
            is_public=False,
            creator=self.user2)
        self.reachable_url = "/{}nodes/{}/".format(API_BASE,
                                                   self.reachable_project._id)
        self.unreachable_url = "/{}nodes/{}/".format(
            API_BASE, self.unreachable_project._id)  # User1 can't access this

    def test_missing_credential_fails(self):
        res = self.app.get(self.unreachable_url, auth=None, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_equal(
            res.json.get("errors")[0]['detail'],
            'Authentication credentials were not provided.')

    def test_invalid_credential_fails(self):
        res = self.app.get(self.unreachable_url,
                           auth=(self.user1.username, 'invalid password'),
                           expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_equal(
            res.json.get("errors")[0]['detail'], 'Invalid username/password.')

    def test_valid_credential_authenticates_and_has_permissions(self):
        res = self.app.get(self.reachable_url, auth=self.user1.auth)
        assert_equal(res.status_code, 200, msg=res.json)

    def test_valid_credential_authenticates_but_user_lacks_object_permissions(
            self):
        res = self.app.get(self.unreachable_url,
                           auth=self.user1.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 403, msg=res.json)

    def test_valid_credential_but_twofactor_required(self):
        user1_addon = self.user1.get_or_add_addon('twofactor')
        user1_addon.totp_drift = 1
        user1_addon.totp_secret = self.TOTP_SECRET
        user1_addon.is_confirmed = True
        user1_addon.save()

        res = self.app.get(self.reachable_url,
                           auth=self.user1.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_equal(res.headers['X-OSF-OTP'], 'required; app')
        assert_equal(
            res.json.get("errors")[0]['detail'],
            'Must specify two-factor authentication OTP code.')

    def test_valid_credential_twofactor_invalid_otp(self):
        user1_addon = self.user1.get_or_add_addon('twofactor')
        user1_addon.totp_drift = 1
        user1_addon.totp_secret = self.TOTP_SECRET
        user1_addon.is_confirmed = True
        user1_addon.save()

        res = self.app.get(self.reachable_url,
                           auth=self.user1.auth,
                           headers={'X-OSF-OTP': 'invalid otp'},
                           expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_true('X-OSF-OTP' not in res.headers)
        assert_equal(
            res.json.get("errors")[0]['detail'],
            'Invalid two-factor authentication OTP code.')

    def test_valid_credential_twofactor_valid_otp(self):
        user1_addon = self.user1.get_or_add_addon('twofactor')
        user1_addon.totp_drift = 1
        user1_addon.totp_secret = self.TOTP_SECRET
        user1_addon.is_confirmed = True
        user1_addon.save()

        res = self.app.get(
            self.reachable_url,
            auth=self.user1.auth,
            headers={'X-OSF-OTP': _valid_code(self.TOTP_SECRET)})
        assert_equal(res.status_code, 200)
Example #19
0
class TestAuthBasicAuthentication(OsfTestCase):

    TOTP_SECRET = 'b8f85986068f8079aa9d'

    def setUp(self):
        super(TestAuthBasicAuthentication, self).setUp()
        self.user1 = AuthUserFactory()
        self.user2 = AuthUserFactory()

        # Test projects for which a given user DOES and DOES NOT  have appropriate permissions
        self.reachable_project = ProjectFactory(title="Private Project User 1", is_public=False, creator=self.user1)
        self.unreachable_project = ProjectFactory(title="Private Project User 2", is_public=False, creator=self.user2)
        self.reachable_url = self.reachable_project.web_url_for('view_project')
        self.unreachable_url = self.unreachable_project.web_url_for('view_project')

    def test_missing_credential_fails(self):
        res = self.app.get(self.unreachable_url, auth=None, expect_errors=True)
        assert_equal(res.status_code, 302)
        assert_true('Location' in res.headers)
        assert_true('/login' in res.headers['Location'])

    def test_invalid_credential_fails(self):
        res = self.app.get(self.unreachable_url, auth=(self.user1.username, 'invalid password'), expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_true('<h2 id=\'error\' data-http-status-code="401">Unauthorized</h2>' in res.body)

    def test_valid_credential_authenticates_and_has_permissions(self):
        res = self.app.get(self.reachable_url, auth=self.user1.auth)
        assert_equal(res.status_code, 200)

    def test_valid_credential_authenticates_but_user_lacks_object_permissions(self):
        res = self.app.get(self.unreachable_url, auth=self.user1.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_valid_credential_but_twofactor_required(self):
        user1_addon = self.user1.get_or_add_addon('twofactor')
        user1_addon.totp_drift = 1
        user1_addon.totp_secret = self.TOTP_SECRET
        user1_addon.is_confirmed = True
        user1_addon.save()

        res = self.app.get(self.reachable_url, auth=self.user1.auth, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_true('<h2 id=\'error\' data-http-status-code="401">Unauthorized</h2>' in res.body)

    def test_valid_credential_twofactor_invalid_otp(self):
        user1_addon = self.user1.get_or_add_addon('twofactor')
        user1_addon.totp_drift = 1
        user1_addon.totp_secret = self.TOTP_SECRET
        user1_addon.is_confirmed = True
        user1_addon.save()

        res = self.app.get(self.reachable_url, auth=self.user1.auth, headers={'X-OSF-OTP': 'invalid otp'}, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_true('<h2 id=\'error\' data-http-status-code="401">Unauthorized</h2>' in res.body)

    def test_valid_credential_twofactor_valid_otp(self):
        user1_addon = self.user1.get_or_add_addon('twofactor')
        user1_addon.totp_drift = 1
        user1_addon.totp_secret = self.TOTP_SECRET
        user1_addon.is_confirmed = True
        user1_addon.save()

        res = self.app.get(self.reachable_url, auth=self.user1.auth, headers={'X-OSF-OTP': _valid_code(self.TOTP_SECRET)})
        assert_equal(res.status_code, 200)
Example #20
0
class TestUserSettings(OsfTestCase):
    @classmethod
    def setUpClass(cls):
        init_mock_addon()
        super(TestUserSettings, cls).setUpClass()

    @classmethod
    def tearDownClass(cls):
        remove_mock_addon()
        super(TestUserSettings, cls).tearDownClass()

    def setUp(self):
        super(TestUserSettings, self).setUp()
        self.user = AuthUserFactory()

        self.user_settings = self.user.get_or_add_addon(
            MockUserSettings.oauth_provider.short_name)

        self.external_account = ExternalAccountFactory()
        self.user.external_accounts.append(self.external_account)
        self.user.save()

        self.project = ProjectFactory(creator=self.user)

    def tearDown(self):
        super(TestUserSettings, self).tearDown()

    def test_connected_accounts_empty(self):
        self.user.external_accounts = []

        assert_equal(self.user_settings.external_accounts, [])

    def test_connected_accounts(self):
        assert_equal(self.user_settings.external_accounts,
                     [self.external_account])

    def test_verify_false_no_grants(self):
        assert_false(
            self.user_settings.verify_oauth_access(
                external_account=self.external_account, node=self.project))

    def test_verify_false_with_grants(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account, node=ProjectFactory())

        assert_false(
            self.user_settings.verify_oauth_access(
                external_account=self.external_account, node=self.project))

    def test_verify_false_metadata(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account,
            node=self.project,
            metadata={'foo': 'bar'})

        assert_false(
            self.user_settings.verify_oauth_access(
                external_account=self.external_account,
                node=self.project,
                metadata={'baz': 'qiz'}))

    def test_verify_true(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account, node=self.project)

        assert_true(
            self.user_settings.verify_oauth_access(
                external_account=self.external_account, node=self.project))

    def test_verify_true_with_metadata(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account,
            node=self.project,
            metadata={'foo': 'bar'})

        assert_true(
            self.user_settings.verify_oauth_access(
                external_account=self.external_account,
                node=self.project,
                metadata={'foo': 'bar'}))

    def test_grant(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account, node=self.project)

        assert_equal(self.user_settings.oauth_grants,
                     {self.project._id: {
                         self.external_account._id: {}
                     }})

    def test_grant_not_owned(self):
        self.user.external_accounts = []

        with assert_raises(PermissionsError):
            self.user_settings.grant_oauth_access(
                external_account=self.external_account, node=self.project)

        assert_equal(self.user_settings.oauth_grants, {})

    def test_grant_metadata(self):
        self.user_settings.grant_oauth_access(
            external_account=self.external_account,
            node=self.project,
            metadata={'foo': 'bar'})

        assert_equal(
            self.user_settings.oauth_grants,
            {self.project._id: {
                self.external_account._id: {
                    'foo': 'bar'
                }
            }})

    def test_on_delete(self):
        node_settings = self.project.get_or_add_addon(
            MockUserSettings.oauth_provider.short_name,
            auth=Auth(user=self.user))

        node_settings.set_auth(external_account=self.external_account,
                               user=self.user)

        self.user.delete_addon(MockUserSettings.oauth_provider.short_name)

        node_settings.reload()

        assert_is_none(node_settings.external_account)
        assert_is_none(node_settings.user_settings)
Example #21
0
class TestAuthBasicAuthentication(OsfTestCase):

    TOTP_SECRET = 'b8f85986068f8079aa9d'

    def setUp(self):
        super(TestAuthBasicAuthentication, self).setUp()
        self.user1 = AuthUserFactory()
        self.user2 = AuthUserFactory()

        # Test projects for which a given user DOES and DOES NOT  have appropriate permissions
        self.reachable_project = ProjectFactory(title="Private Project User 1",
                                                is_public=False,
                                                creator=self.user1)
        self.unreachable_project = ProjectFactory(
            title="Private Project User 2",
            is_public=False,
            creator=self.user2)
        self.reachable_url = self.reachable_project.web_url_for('view_project')
        self.unreachable_url = self.unreachable_project.web_url_for(
            'view_project')

    def test_missing_credential_fails(self):
        res = self.app.get(self.unreachable_url, auth=None, expect_errors=True)
        assert_equal(res.status_code, 302)
        assert_true('Location' in res.headers)
        assert_true('/login' in res.headers['Location'])

    def test_invalid_credential_fails(self):
        res = self.app.get(self.unreachable_url,
                           auth=(self.user1.username, 'invalid password'),
                           expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_true(
            '<h2 id=\'error\' data-http-status-code="401">Unauthorized</h2>' in
            res.body)

    def test_valid_credential_authenticates_and_has_permissions(self):
        res = self.app.get(self.reachable_url, auth=self.user1.auth)
        assert_equal(res.status_code, 200)

    def test_valid_credential_authenticates_but_user_lacks_object_permissions(
            self):
        res = self.app.get(self.unreachable_url,
                           auth=self.user1.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_valid_credential_but_twofactor_required(self):
        user1_addon = self.user1.get_or_add_addon('twofactor')
        user1_addon.totp_drift = 1
        user1_addon.totp_secret = self.TOTP_SECRET
        user1_addon.is_confirmed = True
        user1_addon.save()

        res = self.app.get(self.reachable_url,
                           auth=self.user1.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_true(
            '<h2 id=\'error\' data-http-status-code="401">Unauthorized</h2>' in
            res.body)

    def test_valid_credential_twofactor_invalid_otp(self):
        user1_addon = self.user1.get_or_add_addon('twofactor')
        user1_addon.totp_drift = 1
        user1_addon.totp_secret = self.TOTP_SECRET
        user1_addon.is_confirmed = True
        user1_addon.save()

        res = self.app.get(self.reachable_url,
                           auth=self.user1.auth,
                           headers={'X-OSF-OTP': 'invalid otp'},
                           expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_true(
            '<h2 id=\'error\' data-http-status-code="401">Unauthorized</h2>' in
            res.body)

    def test_valid_credential_twofactor_valid_otp(self):
        user1_addon = self.user1.get_or_add_addon('twofactor')
        user1_addon.totp_drift = 1
        user1_addon.totp_secret = self.TOTP_SECRET
        user1_addon.is_confirmed = True
        user1_addon.save()

        res = self.app.get(
            self.reachable_url,
            auth=self.user1.auth,
            headers={'X-OSF-OTP': _valid_code(self.TOTP_SECRET)})
        assert_equal(res.status_code, 200)
Example #22
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.append(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 tearDown(self):
        GitHubNodeSettings.remove()
        GitHubUserSettings.remove()
        GoogleDriveNodeSettings.remove()
        GoogleDriveUserSettings.remove()

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

    def test_one_user_one_node_one_addon(self):
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['users']['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.append(oauth_settings2)
        self.user.save()
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['users']['enabled'], 1)

    def test_one_user_with_multiple_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.append(oauth_settings)
        self.user.save()
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        googledrive_res = [
            res for res in results if res['provider']['name'] == 'googledrive'
        ][0]
        assert_equal(github_res['users']['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.append(oauth_settings2)
        user.save()
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        assert_equal(github_res['users']['enabled'], 2)
        assert_equal(github_res['users']['authorized'], 1)
        assert_equal(github_res['users']['linked'], 1)

    def test_many_users_each_with_the_same_github_enabled(self):
        user = AuthUserFactory()
        user.add_addon('github')
        user.external_accounts.append(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.append(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.append(oauth_settings)
        self.user.save()
        self.node.add_addon('googledrive', Auth(self.user))
        node_addon = self.node.get_addon('googledrive')
        node_addon.user = self.user.fullname
        node_addon.user_settings = user_addon
        node_addon.external_account = oauth_settings
        node_addon.save()
        results = AddonSnapshot().get_events()
        github_res = [
            res for res in results if res['provider']['name'] == 'github'
        ][0]
        googledrive_res = [
            res for res in results if res['provider']['name'] == 'googledrive'
        ][0]
        assert_equal(github_res['nodes']['total'], 1)
        assert_equal(googledrive_res['nodes']['total'], 1)

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

        node = ProjectFactory(creator=self.user)
        node.add_addon('github', Auth(self.user))
        node_addon = node.get_addon('github')
        node_addon.user = self.user.fullname
        node_addon.repo = '8 (circle)'
        node_addon.user_settings = self.user_addon
        node_addon.external_account = self.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 = User.find().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)

    def test_bookmark_collection_not_counted(self):
        BookmarkCollectionFactory(creator=self.user)
        all_node_count = Node.find().count()

        results = AddonSnapshot().get_events()
        storage_res = [
            res for res in results if res['provider']['name'] == 'osfstorage'
        ][0]
        assert_equal(storage_res['nodes']['connected'], all_node_count - 1)
Example #23
0
class TestGoogleDriveConfigViews(OsfTestCase):
    def setUp(self):
        super(TestGoogleDriveConfigViews, self).setUp()
        self.account = GoogleDriveAccountFactory()
        self.user = AuthUserFactory(external_accounts=[self.account])
        self.user_settings = self.user.get_or_add_addon('googledrive')
        self.project = ProjectFactory(creator=self.user)
        self.project.add_addon('googledrive', Auth(self.user))
        self.node_settings = self.project.get_addon('googledrive')
        self.node_settings.user_settings = self.user_settings
        self.node_settings.save()
        self.user_settings.save()
        # Log user in
        self.app.authenticate(*self.user.auth)

    def test_list_googledrive_accounts_returns_accounts_single(self):
        url = api_url_for('list_googledrive_user_accounts')
        res = self.app.get(url)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['accounts']), 1)
        assert_equal(res.json['accounts'][0]['provider_id'],
                     self.account.provider_id)
        assert_equal(res.json['accounts'][0]['provider_name'],
                     self.account.provider_name)

    def test_list_googledrive_accounts_returns_accounts_multiple(self):
        external_account = GoogleDriveAccountFactory()
        self.user.external_accounts.append(
            external_account)  # self.account is already present
        self.user.save()
        url = api_url_for('list_googledrive_user_accounts')
        res = self.app.get(url)
        assert_equal(res.status_code, 200)
        assert_equal(len(res.json['accounts']), 2)

    def test_googledrive_config_get_return_correct_urls(self):
        url = self.project.api_url_for('googledrive_config_get')
        res = self.app.get(url)
        assert_equal(res.status_code, http.OK)
        result = res.json['result']
        assert_equal(
            result['urls']['accounts'],
            self.project.api_url_for('list_googledrive_user_accounts'))
        assert_equal(result['urls']['auth'],
                     api_url_for('oauth_connect', service_name='googledrive'))
        assert_equal(result['urls']['config'],
                     self.project.api_url_for('googledrive_config_put'))
        assert_equal(result['urls']['deauthorize'],
                     self.project.api_url_for('googledrive_remove_user_auth'))
        assert_equal(result['urls']['files'],
                     self.project.web_url_for('collect_file_trees'))
        assert_equal(result['urls']['folders'],
                     self.project.api_url_for('googledrive_folders'))
        assert_equal(result['urls']['importAuth'],
                     self.project.api_url_for('googledrive_import_user_auth'))
        assert_equal(result['urls']['settings'], web_url_for('user_addons'))

    def test_googledrive_config_get_has_auth(self):
        self.node_settings.set_auth(external_account=self.account,
                                    user=self.user)
        self.node_settings.save()
        url = self.project.api_url_for('googledrive_config_get')
        res = self.app.get(url)
        assert_equal(res.status_code, 200)
        result = res.json['result']
        assert_true(result['nodeHasAuth'])

    def test_googledrive_config_get_does_not_has_auth(self):
        url = self.project.api_url_for('googledrive_config_get')
        res = self.app.get(url)
        result = res.json['result']
        assert_false(result['nodeHasAuth'])

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

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

        # Folder was set
        assert_equal(self.node_settings.folder_path, 'Google Drive/ My Folder')
        # A log event was created
        last_log = self.project.logs[-1]
        assert_equal(last_log.action, 'googledrive_folder_selected')
        params = last_log.params
        assert_equal(params['folder'], ' My Folder')

    def test_googledrive_import_user_auth(self):
        url = self.project.api_url_for('googledrive_import_user_auth',
                                       auth=self.user.auth)
        self.app.put_json(url, {'external_account_id': self.account._id})
        self.node_settings.reload()
        assert_equal(self.node_settings.external_account, self.account)

    def test_googledrive_remove_user_auth(self):
        self.node_settings.set_auth(external_account=self.account,
                                    user=self.user)
        self.node_settings.save()
        assert_equal(self.node_settings.external_account, self.account)
        url = self.project.api_url_for('googledrive_remove_user_auth',
                                       auth=self.user.auth)
        self.app.delete(url)
        self.node_settings.reload()
        assert_equal(self.node_settings.external_account, None)