Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix request creation when headers are the default #198

Merged
merged 5 commits into from
Jun 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions auth0/v3/authentication/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,15 @@ def __init__(self, domain, telemetry=True):

def post(self, url, data=None, headers=None):
request_headers = self.base_headers.copy()
request_headers.update(headers)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was the bug. When headers was None this call would throw.

response = requests.post(url=url, data=json.dumps(data),
headers=request_headers)
request_headers.update(headers or {})
response = requests.post(url=url, json=data, headers=request_headers)
return self._process_response(response)

def get(self, url, params=None, headers=None):
request_headers = self.base_headers.copy()
request_headers.update(headers)
request_headers.update(headers or {})
response = requests.get(url=url, params=params, headers=request_headers)
return response.text
return self._process_response(response)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some response formats where not taken into account. This was the only method not calling _process_response. Now it handles text responses (what was there before), JSON and empty body responses.


def _process_response(self, response):
return self._parse(response).content()
Expand Down
9 changes: 3 additions & 6 deletions auth0/v3/authentication/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ def login(self, client_id, username, password, connection, id_token=None,
'device': device,
'grant_type': grant_type,
'scope': scope,
},
headers={'Content-Type': 'application/json'}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these args were removed because they match the default behavior https://github.com/auth0/auth0-python/blob/master/auth0/v3/authentication/base.py#L24

}
)

def signup(self, client_id, email, password, connection, username=None,
Expand Down Expand Up @@ -67,8 +66,7 @@ def signup(self, client_id, email, password, connection, username=None,

return self.post(
'https://{}/dbconnections/signup'.format(self.domain),
data=body,
headers={'Content-Type': 'application/json'}
data=body
)

def change_password(self, client_id, email, connection, password=None):
Expand All @@ -82,6 +80,5 @@ def change_password(self, client_id, email, connection, password=None):
'email': email,
'password': password,
'connection': connection,
},
headers={'Content-Type': 'application/json'}
}
)
1 change: 0 additions & 1 deletion auth0/v3/authentication/delegated.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,5 @@ def get_token(self, client_id, target, api_type, grant_type,

return self.post(
'https://{}/delegation'.format(self.domain),
headers={'Content-Type': 'application/json'},
data=data
)
15 changes: 5 additions & 10 deletions auth0/v3/authentication/get_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ def authorization_code(self, client_id, client_secret, code,
'code': code,
'grant_type': grant_type,
'redirect_uri': redirect_uri,
},
headers={'Content-Type': 'application/json'}
}
)

def authorization_code_pkce(self, client_id, code_verifier, code,
Expand Down Expand Up @@ -79,8 +78,7 @@ def authorization_code_pkce(self, client_id, code_verifier, code,
'code': code,
'grant_type': grant_type,
'redirect_uri': redirect_uri,
},
headers={'Content-Type': 'application/json'}
}
)

def client_credentials(self, client_id, client_secret, audience,
Expand Down Expand Up @@ -113,8 +111,7 @@ def client_credentials(self, client_id, client_secret, audience,
'client_secret': client_secret,
'audience': audience,
'grant_type': grant_type,
},
headers={'Content-Type': 'application/json'}
}
)

def login(self, client_id, client_secret, username, password, scope, realm,
Expand Down Expand Up @@ -164,8 +161,7 @@ def login(self, client_id, client_secret, username, password, scope, realm,
'scope': scope,
'audience': audience,
'grant_type': grant_type
},
headers={'Content-Type': 'application/json'}
}
)

def refresh_token(self, client_id, client_secret, refresh_token, grant_type='refresh_token'):
Expand Down Expand Up @@ -194,6 +190,5 @@ def refresh_token(self, client_id, client_secret, refresh_token, grant_type='ref
'client_secret': client_secret,
'refresh_token': refresh_token,
'grant_type': grant_type
},
headers={'Content-Type': 'application/json'}
}
)
6 changes: 2 additions & 4 deletions auth0/v3/authentication/logout.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,10 @@ def logout(self, client_id, return_to, federated=False):
if federated is True:
return self.get(
'https://{}/v2/logout?federated&client_id={}&returnTo={}'.format(
self.domain, client_id, return_to),
headers={'Content-Type': 'application/json'}
self.domain, client_id, return_to)
)
return self.get(
'https://{}/v2/logout?client_id={}&returnTo={}'.format(self.domain,
client_id,
return_to),
headers={'Content-Type': 'application/json'}
return_to)
)
9 changes: 3 additions & 6 deletions auth0/v3/authentication/passwordless.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ def email(self, client_id, email, send='link', auth_params=None):
'email': email,
'send': send,
'authParams': auth_params
},
headers={'Content-Type': 'application/json'}
}
)

def sms(self, client_id, phone_number):
Expand All @@ -55,8 +54,7 @@ def sms(self, client_id, phone_number):
'client_id': client_id,
'connection': 'sms',
'phone_number': phone_number,
},
headers={'Content-Type': 'application/json'}
}
)

def sms_login(self, client_id, phone_number, code, scope='openid'):
Expand All @@ -72,6 +70,5 @@ def sms_login(self, client_id, phone_number, code, scope='openid'):
'username': phone_number,
'password': code,
'scope': scope,
},
headers={'Content-Type': 'application/json'}
}
)
3 changes: 1 addition & 2 deletions auth0/v3/authentication/social.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,5 @@ def login(self, client_id, access_token, connection, scope='openid'):
'access_token': access_token,
'connection': connection,
'scope': scope,
},
headers={'Content-Type': 'application/json'}
}
)
3 changes: 1 addition & 2 deletions auth0/v3/authentication/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,5 @@ def tokeninfo(self, jwt):
warnings.warn("/tokeninfo will be deprecated in future releases", DeprecationWarning)
return self.post(
url='https://{}/tokeninfo'.format(self.domain),
data={'id_token': jwt},
headers={'Content-Type': 'application/json'}
data={'id_token': jwt}
)
6 changes: 3 additions & 3 deletions auth0/v3/management/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def get(self, url, params=None):
def post(self, url, data=None):
headers = self.base_headers.copy()

response = requests.post(url, data=json.dumps(data or {}), headers=headers)
response = requests.post(url, json=data, headers=headers)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No longer need to explicitly convert python dictionaries to "JSON text"

return self._process_response(response)

def file_post(self, url, data=None, files=None):
Expand All @@ -59,13 +59,13 @@ def file_post(self, url, data=None, files=None):
def patch(self, url, data=None):
headers = self.base_headers.copy()

response = requests.patch(url, data=json.dumps(data or {}), headers=headers)
response = requests.patch(url, json=data, headers=headers)
return self._process_response(response)

def put(self, url, data=None):
headers = self.base_headers.copy()

response = requests.put(url, data=json.dumps(data or {}), headers=headers)
response = requests.put(url, json=data, headers=headers)
return self._process_response(response)

def delete(self, url, params=None):
Expand Down
50 changes: 47 additions & 3 deletions auth0/v3/test/authentication/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,25 @@ def test_post(self, mock_post):

data = ab.post('the-url', data={'a': 'b'}, headers={'c': 'd'})

mock_post.assert_called_with(url='the-url', data='{"a": "b"}',
mock_post.assert_called_with(url='the-url', json={'a': 'b'},
headers={'c': 'd', 'Content-Type': 'application/json'})

self.assertEqual(data, {'x': 'y'})

@mock.patch('requests.post')
def test_post_with_defaults(self, mock_post):
ab = AuthenticationBase('auth0.com', telemetry=False)

mock_post.return_value.status_code = 200
mock_post.return_value.text = '{"x": "y"}'

# Only required params are passed
data = ab.post('the-url')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no headers value is passed, so default of None will kick in. This asserts the bug is no longer present


mock_post.assert_called_with(url='the-url', json=None,
headers={'Content-Type': 'application/json'})

self.assertEqual(data, {'x': 'y'})

@mock.patch('requests.post')
def test_post_includes_telemetry(self, mock_post):
Expand All @@ -67,7 +82,7 @@ def test_post_includes_telemetry(self, mock_post):
self.assertEqual(mock_post.call_count, 1)
call_kwargs = mock_post.call_args[1]
self.assertEqual(call_kwargs['url'], 'the-url')
self.assertEqual(call_kwargs['data'], '{"a": "b"}')
self.assertEqual(call_kwargs['json'], {'a': 'b'})
headers = call_kwargs['headers']
self.assertEqual(headers['c'], 'd')
self.assertEqual(headers['Content-Type'], 'application/json')
Expand Down Expand Up @@ -157,6 +172,35 @@ def test_post_error_with_no_response_text(self, mock_post):
'a0.sdk.internal.unknown')
self.assertEqual(context.exception.message, '')

@mock.patch('requests.get')
def test_get(self, mock_get):
ab = AuthenticationBase('auth0.com', telemetry=False)

mock_get.return_value.status_code = 200
mock_get.return_value.text = '{"x": "y"}'

data = ab.get('the-url', params={'a': 'b'}, headers={'c': 'd'})

mock_get.assert_called_with(url='the-url', params={'a': 'b'},
headers={'c': 'd', 'Content-Type': 'application/json'})

self.assertEqual(data, {'x': 'y'})

@mock.patch('requests.get')
def test_get_with_defaults(self, mock_get):
ab = AuthenticationBase('auth0.com', telemetry=False)

mock_get.return_value.status_code = 200
mock_get.return_value.text = '{"x": "y"}'

# Only required params are passed
data = ab.get('the-url')

mock_get.assert_called_with(url='the-url', params=None,
headers={'Content-Type': 'application/json'})

self.assertEqual(data, {'x': 'y'})

@mock.patch('requests.get')
def test_get_includes_telemetry(self, mock_get):
ab = AuthenticationBase('auth0.com')
Expand All @@ -176,4 +220,4 @@ def test_get_includes_telemetry(self, mock_get):
self.assertIn('User-Agent', headers)
self.assertIn('Auth0-Client', headers)

self.assertEqual(data, '{"x": "y"}')
self.assertEqual(data, {"x": "y"})
12 changes: 0 additions & 12 deletions auth0/v3/test/authentication/test_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ def test_login(self, mock_post):
'grant_type': 'gt',
'scope': 'openid profile',
})
self.assertEqual(kwargs['headers'], {
'Content-Type': 'application/json'
})

@mock.patch('auth0.v3.authentication.database.Database.post')
def test_signup(self, mock_post):
Expand All @@ -58,9 +55,6 @@ def test_signup(self, mock_post):
'username': None,
'user_metadata': None
})
self.assertEqual(kwargs['headers'], {
'Content-Type': 'application/json'
})


# Using also username and metadata
Expand Down Expand Up @@ -88,9 +82,6 @@ def test_signup(self, mock_post):
'username': 'usr',
'user_metadata': sample_meta
})
self.assertEqual(kwargs['headers'], {
'Content-Type': 'application/json'
})

@mock.patch('auth0.v3.authentication.database.Database.post')
def test_change_password(self, mock_post):
Expand All @@ -112,6 +103,3 @@ def test_change_password(self, mock_post):
'password': 'pswd',
'connection': 'conn',
})
self.assertEqual(kwargs['headers'], {
'Content-Type': 'application/json'
})
6 changes: 0 additions & 6 deletions auth0/v3/test/authentication/test_delegated.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ def test_get_token_id_token(self, mock_post):
'scope': 'openid profile',
'api_type': 'apt',
})
self.assertEqual(kwargs['headers'], {
'Content-Type': 'application/json'
})

@mock.patch('auth0.v3.authentication.delegated.Delegated.post')
def test_get_token_refresh_token(self, mock_post):
Expand All @@ -54,9 +51,6 @@ def test_get_token_refresh_token(self, mock_post):
'scope': 'openid',
'api_type': 'apt',
})
self.assertEqual(kwargs['headers'], {
'Content-Type': 'application/json'
})

@mock.patch('auth0.v3.authentication.delegated.Delegated.post')
def test_get_token_value_error(self, mock_post):
Expand Down
17 changes: 1 addition & 16 deletions auth0/v3/test/authentication/test_get_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ def test_authorization_code(self, mock_post):
'grant_type': 'gt',
'redirect_uri': 'idt'
})
self.assertEqual(kwargs['headers'], {
'Content-Type': 'application/json'
})

@mock.patch('auth0.v3.authentication.get_token.GetToken.post')
def test_authorization_code_pkce(self, mock_post):
Expand All @@ -51,9 +48,6 @@ def test_authorization_code_pkce(self, mock_post):
'grant_type': 'gt',
'redirect_uri': 'idt'
})
self.assertEqual(kwargs['headers'], {
'Content-Type': 'application/json'
})

@mock.patch('auth0.v3.authentication.get_token.GetToken.post')
def test_client_credentials(self, mock_post):
Expand All @@ -74,9 +68,6 @@ def test_client_credentials(self, mock_post):
'audience': 'aud',
'grant_type': 'gt'
})
self.assertEqual(kwargs['headers'], {
'Content-Type': 'application/json'
})

@mock.patch('auth0.v3.authentication.get_token.GetToken.post')
def test_login(self, mock_post):
Expand Down Expand Up @@ -105,9 +96,6 @@ def test_login(self, mock_post):
'audience': 'aud',
'grant_type': 'gt'
})
self.assertEqual(kwargs['headers'], {
'Content-Type': 'application/json'
})

@mock.patch('auth0.v3.authentication.get_token.GetToken.post')
def test_refresh_token(self, mock_post):
Expand All @@ -126,7 +114,4 @@ def test_refresh_token(self, mock_post):
'client_secret': 'clsec',
'refresh_token': 'rt',
'grant_type': 'gt'
})
self.assertEqual(kwargs['headers'], {
'Content-Type': 'application/json'
})
})
8 changes: 0 additions & 8 deletions auth0/v3/test/authentication/test_logout.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,7 @@ def test_logout(self, mock_get):
return_to='rto')

args, kwargs = mock_get.call_args

self.assertEqual(args[0], 'https://my.domain.com/v2/logout?client_id=cid&returnTo=rto')
self.assertEqual(kwargs['headers'], {
'Content-Type': 'application/json'
})

@mock.patch('auth0.v3.authentication.logout.Logout.get')
def test_federated_logout(self, mock_get):
Expand All @@ -30,8 +26,4 @@ def test_federated_logout(self, mock_get):
federated=True)

args, kwargs = mock_get.call_args

self.assertEqual(args[0], 'https://my.domain.com/v2/logout?federated&client_id=cid&returnTo=rto')
self.assertEqual(kwargs['headers'], {
'Content-Type': 'application/json'
})
Loading