コード例 #1
0
    def test_does_not_need_refresh(self):
        self.provider.refresh_time = 1
        external_account = ExternalAccountFactory(
            provider='mock2',
            provider_id='mock_provider_id',
            provider_name='Mock Provider',
            oauth_key='old_key',
            oauth_secret='old_secret',
            refresh_token='old_refresh',
            expires_at=datetime.utcfromtimestamp(time.time() + 200),
        )

        # mock a successful call to the provider to refresh tokens
        httpretty.register_uri(httpretty.POST,
                               self.provider.auto_refresh_url,
                               body=json.dumps(
                                   {'err_msg': 'Should not be hit'}),
                               status=500)

        # .reload() has the side effect of rounding the microsends down to 3 significant figures
        # (e.g. DT(YMDHMS, 365420) becomes DT(YMDHMS, 365000)),
        # but must occur after possible refresh to reload tokens.
        # Doing so before allows the `old_expiry == EA.expires_at` comparison to work.
        external_account.reload()
        old_expiry = external_account.expires_at
        self.provider.account = external_account
        self.provider.refresh_oauth_key(force=False)
        external_account.reload()

        assert_equal(external_account.oauth_key, 'old_key')
        assert_equal(external_account.refresh_token, 'old_refresh')
        assert_equal(external_account.expires_at, old_expiry)
コード例 #2
0
    def test_does_need_refresh(self):
        external_account = ExternalAccountFactory(
            provider='mock2',
            provider_id='mock_provider_id',
            provider_name='Mock Provider',
            oauth_key='old_key',
            oauth_secret='old_secret',
            expires_at=datetime.utcfromtimestamp(time.time() - 200),
        )

        # mock a successful call to the provider to refresh tokens
        httpretty.register_uri(httpretty.POST,
                               self.provider.auto_refresh_url,
                               body=json.dumps({
                                   'access_token':
                                   'refreshed_access_token',
                                   'expires_in':
                                   3600,
                                   'refresh_token':
                                   'refreshed_refresh_token'
                               }))

        old_expiry = external_account.expires_at
        self.provider.account = external_account
        self.provider.refresh_oauth_key(force=False)
        external_account.reload()

        assert_equal(external_account.oauth_key, 'refreshed_access_token')
        assert_equal(external_account.refresh_token, 'refreshed_refresh_token')
        assert_not_equal(external_account.expires_at, old_expiry)
        assert_true(external_account.expires_at > old_expiry)
コード例 #3
0
ファイル: test_oauth.py プロジェクト: ubiquitypress/osf.io
    def test_multiple_users_associated(self):
        # Create only one ExternalAccount for multiple OSF users
        #
        # For some providers (ex: GitHub), the act of completing the OAuth flow
        # revokes previously generated credentials. In addition, there is often no
        # way to know the user's id on the external service until after the flow
        # has completed.
        #
        # Having only one ExternalAccount instance per account on the external
        # service means that connecting subsequent OSF users to the same external
        # account will not invalidate the credentials used by the OSF for users
        # already associated.
        user_a = UserFactory()
        external_account = ExternalAccountFactory(
            provider='mock2',
            provider_id='mock_provider_id',
            provider_name='Mock Provider',
        )
        user_a.external_accounts.append(external_account)
        user_a.save()

        user_b = UserFactory()

        # Mock the exchange of the code for an access token
        _prepare_mock_oauth2_handshake_response()

        # Fake a request context for the callback
        with self.app.app.test_request_context(
                path="/oauth/callback/mock2/",
                query_string="code=mock_code&state=mock_state"
        ) as ctx:

            # make sure the user is logged in
            authenticate(user=user_b, access_token=None, response=None)

            session.data['oauth_states'] = {
                self.provider.short_name: {
                    'state': 'mock_state',
                },
            }
            session.save()

            # do the key exchange
            self.provider.auth_callback(user=user_b)

        user_a.reload()
        user_b.reload()
        external_account.reload()

        assert_equal(
            user_a.external_accounts,
            user_b.external_accounts,
        )

        assert_equal(
            ExternalAccount.find().count(),
            1
        )
コード例 #4
0
ファイル: test_addons_oauth.py プロジェクト: wearpants/osf.io
 def setUp(self):
     super(TestNodeSettings, self).setUp()
     self.project = ProjectFactory()
     self.user = self.project.creator
     self.node_settings = self.project.get_or_add_addon(
         MockNodeSettings.oauth_provider.short_name,
         auth=Auth(user=self.user))
     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()
コード例 #5
0
ファイル: utils.py プロジェクト: rafaeldelucena/osf.io
def create_external_account(host='foo.bar.baz', token='doremi-abc-123'):
    """Creates external account for Dataverse with fields populated the same
    way as `dataverse_add_user_account`"""

    return ExternalAccountFactory(
        provider='dataverse',
        provider_name='Dataverse',
        display_name=host,
        oauth_key=host,
        oauth_secret=token,
        # Note: provider_id in the addon is currently the same as oauth_secret,
        # but here we will let it be generated by sequence to avoid
        # running into duplicate modular ODM entries.
    )
コード例 #6
0
ファイル: test_oauth.py プロジェクト: ubiquitypress/osf.io
    def test_callback_wrong_user(self):
        # Reject temporary credentials not assigned to the user
        #
        # This prohibits users from associating their external account with
        # another user's OSF account by using XSS or similar attack vector to
        # complete the OAuth flow using the logged-in user but their own account
        # on the external service.
        #
        # If the OSF were to allow login via OAuth with the provider in question,
        # this would allow attackers to hijack OSF accounts with a simple script
        # injection.

        # mock a successful call to the provider to exchange temp keys for
        #   permanent keys
        httpretty.register_uri(
            httpretty.POST,
            'http://mock1a.com/callback',
             body='oauth_token=perm_token'
                  '&oauth_token_secret=perm_secret'
                  '&oauth_callback_confirmed=true',
        )

        user = UserFactory()
        account = ExternalAccountFactory(
            provider="mock1a",
            provider_name='Mock 1A',
            oauth_key="temp_key",
            oauth_secret="temp_secret",
            temporary=True
        )
        account.save()
        # associate this ExternalAccount instance with the user
        user.external_accounts.append(account)
        user.save()

        malicious_user = UserFactory()

        # Fake a request context for the callback
        with self.app.app.test_request_context(
                path="/oauth/callback/mock1a/",
                query_string="oauth_token=temp_key&oauth_verifier=mock_verifier"
        ):
            # make sure the user is logged in
            authenticate(user=malicious_user, access_token=None, response=None)

            with assert_raises(PermissionsError):
                # do the key exchange
                self.provider.auth_callback(user=malicious_user)
コード例 #7
0
    def test_refresh_without_account_or_refresh_url(self):
        external_account = ExternalAccountFactory(
            provider='mock2',
            provider_id='mock_provider_id',
            provider_name='Mock Provider',
            oauth_key='old_key',
            oauth_secret='old_secret',
            expires_at=datetime.utcfromtimestamp(time.time() + 200))

        # mock a successful call to the provider to refresh tokens
        httpretty.register_uri(httpretty.POST,
                               self.provider.auto_refresh_url,
                               body=json.dumps(
                                   {'err_msg': 'Should not be hit'}),
                               status=500)

        ret = self.provider.refresh_oauth_key(force=False)
        assert_false(ret)
コード例 #8
0
ファイル: test_oauth.py プロジェクト: ubiquitypress/osf.io
    def test_disconnect_with_multiple_connected(self):
        # Disconnect an account connected to multiple users from one user
        external_account = ExternalAccountFactory(
            provider='mock2',
            provider_id='mock_provider_id',
            provider_name='Mock Provider',
        )
        self.user.external_accounts.append(external_account)
        self.user.save()

        other_user = UserFactory()
        other_user.external_accounts.append(external_account)
        other_user.save()

        response = self.app.delete(
            api_url_for('oauth_disconnect',
                        external_account_id=external_account._id),
            auth=self.user.auth
        )

        # Request succeeded
        assert_equal(
            response.status_code,
            http.OK,
        )

        self.user.reload()

        # External account has been disassociated with the user
        assert_not_in(
            external_account,
            self.user.external_accounts,
        )

        # External account is still in the database
        assert_equal(ExternalAccount.find().count(), 1)

        other_user.reload()

        # External account is still associated with the other user
        assert_in(
            external_account,
            other_user.external_accounts,
        )
コード例 #9
0
    def test_refresh_oauth_key_does_not_need_refresh(self):
        external_account = ExternalAccountFactory(
            provider='mock2',
            provider_id='mock_provider_id',
            provider_name='Mock Provider',
            oauth_key='old_key',
            oauth_secret='old_secret',
            expires_at=0  # causes `.needs_refresh()` to return False
        )

        # mock a successful call to the provider to refresh tokens
        httpretty.register_uri(httpretty.POST,
                               self.provider.auto_refresh_url,
                               body=json.dumps(
                                   {'err_msg': 'Should not be hit'}),
                               status=500)

        self.provider.account = external_account
        ret = self.provider.refresh_oauth_key(force=False)
        assert_false(ret)
コード例 #10
0
ファイル: test_oauth.py プロジェクト: ubiquitypress/osf.io
    def test_disconnect(self):
        # Disconnect an external account from a user
        external_account = ExternalAccountFactory(
            provider='mock2',
            provider_id='mock_provider_id',
            provider_name='Mock Provider',
        )
        self.user.external_accounts.append(external_account)
        self.user.save()

        # If the external account isn't attached, this test has no meaning
        assert_equal(ExternalAccount.find().count(), 1)
        assert_in(
            external_account,
            self.user.external_accounts,
        )

        response = self.app.delete(
            api_url_for('oauth_disconnect',
                        external_account_id=external_account._id),
            auth=self.user.auth
        )

        # Request succeeded
        assert_equal(
            response.status_code,
            http.OK,
        )

        self.user.reload()
        # external_account.reload()

        # External account has been disassociated with the user
        assert_not_in(
            external_account,
            self.user.external_accounts,
        )

        # External account is still in the database
        assert_equal(ExternalAccount.find().count(), 1)
コード例 #11
0
    def test_force_refresh_with_expired_credentials(self):
        external_account = ExternalAccountFactory(
            provider='mock2',
            provider_id='mock_provider_id',
            provider_name='Mock Provider',
            oauth_key='old_key',
            oauth_secret='old_secret',
            expires_at=datetime.utcfromtimestamp(
                time.time() -
                10000)  # Causes has_expired_credentials to be True
        )
        self.provider.account = external_account

        # mock a failing call to the provider to refresh tokens
        httpretty.register_uri(httpretty.POST,
                               self.provider.auto_refresh_url,
                               body=json.dumps({
                                   'error': 'invalid_grant',
                               }),
                               status=401)

        with assert_raises(OAuth2Error):
            ret = self.provider.refresh_oauth_key(force=True)