def refresh(self, refresh_token=None): """Gets fresh access_token and refresh_token :param refresh_token: Refresh Token :raises ValueError: if Refresh Token value not specified :raises `intuitlib.exceptions.AuthClientError`: if response status != 200 """ token = refresh_token or self.refresh_token if token is None: raise ValueError('Refresh token not specified') headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': get_auth_header(self.client_id, self.client_secret) } body = {'grant_type': 'refresh_token', 'refresh_token': token} send_request('POST', self.token_endpoint, headers, self, body=urlencode(body), session=self)
def revoke(self, token=None): """Revokes access to QBO company/User Info using either valid Refresh Token or Access Token :param token: Refresh Token or Access Token to revoke :raises ValueError: if Refresh Token or Access Token value not specified :raises `intuitlib.exceptions.AuthClientError`: if response status != 200 :return: True if token successfully revoked """ token_to_revoke = token or self.refresh_token or self.access_token if token_to_revoke is None: raise ValueError('Token to revoke not specified') headers = { 'Content-Type': 'application/json', 'Authorization': get_auth_header(self.client_id, self.client_secret) } body = {'token': token_to_revoke} send_request('POST', self.revoke_endpoint, headers, self, body=json.dumps(body), session=self) return True
def test_send_request_session_bad(self, mock_post): mock_resp = self.mock_request(status=400, content={'access_token': 'testaccess'}) mock_post.return_value = mock_resp session = requests.Session() with pytest.raises(AuthClientError): send_request('POST', 'url', {}, self.auth_client, body={}, session=session)
def get_bearer_token(self, auth_code, realm_id=None): """Gets access_token and refresh_token using authorization code :param auth_code: Authorization code received from redirect_uri :param realm_id: Realm ID/Company ID of the QBO company :raises `intuitlib.exceptions.AuthClientError`: if response status != 200 """ realm = realm_id or self.realm_id if realm is not None: self.realm_id = realm headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': get_auth_header(self.client_id, self.client_secret) } body = { 'grant_type': 'authorization_code', 'code': auth_code, 'redirect_uri': self.redirect_uri } send_request('POST', self.token_endpoint, headers, self, body=urlencode(body), session=self)
def test_send_request_session_ok(self, mock_post): mock_resp = self.mock_request(status=200, content={'access_token': 'testaccess'}) mock_post.return_value = mock_resp session = requests.Session() send_request('POST', 'url', {}, self.auth_client, body={}, session=session) assert self.auth_client.access_token == 'testaccess'
def migrate(consumer_key, consumer_secret, access_token, access_secret, auth_client, scopes): """Migrates OAuth1 tokens to OAuth2 tokens :param consumer_key: OAuth1 Consumer Key :param consumer_secret: OAuth1 Consumer Secret :param access_token: OAuth1 Access Token :param access_secret: OAuth1 Access Secret :param auth_client: AuthClient for OAuth2 specs :type auth_client: `intuitlib.client.AuthClient` :param scopes: list of `intuitlib.enum.Scopes` :raises AuthClientError: if response status != 200 """ if auth_client.environment.lower() == 'production': migration_url = MIGRATION_URL['production'] else: migration_url = MIGRATION_URL['sandbox'] auth_header = OAuth1(consumer_key, consumer_secret, access_token, access_secret) headers = { 'Content-Type': 'application/json', } body = { 'scope': scopes_to_string(scopes), 'redirect_uri': auth_client.redirect_uri, 'client_id': auth_client.client_id, 'client_secret': auth_client.client_secret } send_request('POST', migration_url, headers, auth_client, body=json.dumps(body), oauth1_header=auth_header)
def get_user_info(self, access_token=None): """Gets User Info based on OpenID scopes specified :param access_token: Access token :raises ValueError: if Refresh Token or Access Token value not specified :raises `intuitlib.exceptions.AuthClientError`: if response status != 200 :return: Requests object """ token = access_token or self.access_token if token is None: raise ValueError('Acceess token not specified') headers = { 'Authorization': 'Bearer {0}'.format(token) } return send_request('GET', self.user_info_url, headers, self, session=self)
def refresh(self, refresh_token=None): """Gets fresh access_token and refresh_token :param refresh_token: Refresh Token :returns: True if token was successfully refreshed, False otherwise :raises ValueError: if Refresh Token value not specified :raises `intuitlib.exceptions.AuthClientError`: if response status != 200 """ token = refresh_token or self.refresh_token if token is None: raise ValueError('Refresh token not specified') headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': get_auth_header(self.client_id, self.client_secret) } body = {'grant_type': 'refresh_token', 'refresh_token': token} response = send_request('POST', self.token_endpoint, headers, self, body=urlencode(body), session=self) response.raise_for_status() if response.status_code == 200: data = json.loads(response.text) self.access_token = data["access_token"] self.expires_in = data["expires_in"] self.refresh_token = data["refresh_token"] self.x_refresh_token_expires_in = data[ "x_refresh_token_expires_in"] return True return False
def test_send_request_bad_request(self, mock_post): mock_resp = self.mock_request(status=400) mock_post.return_value = mock_resp with pytest.raises(AuthClientError): send_request('POST', 'url', {}, '', body={})