def setUp(self): # Create client test authentication token self.client_token = 'SOMEAUTHTESTINGTOKENHERE2122' token_info = { 'timestamp': '12/12/12 12:12:00', 'client_id': 'test123123123', 'grant_type': 'client' } r_client.hmset(self.client_token, token_info) r_client.expire(self.client_token, 5) # Create username test authentication token self.user_token = 'SOMEAUTHTESTINGTOKENHEREUSERNAME' token_info = { 'timestamp': '12/12/12 12:12:00', 'client_id': 'testuser', 'grant_type': 'password', 'user': '******' } r_client.hmset(self.user_token, token_info) r_client.expire(self.user_token, 5) # Create test access limit token self.user_rate_key = '[email protected]_daily_limit' r_client.setex(self.user_rate_key, 5, 2) super(OAuth2BaseHandlerTests, self).setUp()
def set_token(self, client_id, grant_type, user=None, timeout=3600): """Create access token for the client on redis and send json response Parameters ---------- client_id : str Client that requested the token grant_type : str Type of key being requested user : str, optional If password grant type requested, the user requesting the key. timeout : int, optional The timeout, in seconds, for the token. Default 3600 Returns ------- Writes token information JSON in the form expected by RFC6750: {'access_token': token, 'token_type': 'Bearer', 'expires_in': timeout} access_token: the actual token to use token_type: 'Bearer', which is the expected token type for Oauth2 expires_in: time to token expiration, in seconds. """ token = self.generate_access_token() token_info = { 'timestamp': datetime.datetime.now().strftime('%m-%d-%y %H:%M:%S'), 'client_id': client_id, 'grant_type': grant_type } if user: token_info['user'] = user r_client.hmset(token, token_info) r_client.expire(token, timeout) if grant_type == 'password': # Check if client has access limit key, and if not, create it limit_key = '%s_%s_daily_limit' % (client_id, user) limiter = r_client.get(limit_key) if limiter is None: # Set limit to 5,000 requests per day r_client.setex(limit_key, 86400, 5000) self.write({ 'access_token': token, 'token_type': 'Bearer', 'expires_in': timeout }) self.finish()
def test_authenticate_header_username(self): obs = self.get('/qiita_db/artifacts/1/', headers={ 'Authorization': 'Bearer ' + self.user_token}) self.assertEqual(obs.code, 200) # Check rate limiting works self.assertEqual(int(r_client.get(self.user_rate_key)), 1) r_client.setex('[email protected]_daily_limit', 1, 0) obs = self.get('/qiita_db/artifacts/100/', headers={ 'Authorization': 'Bearer ' + self.user_token}) exp = {'error': 'invalid_grant', 'error_description': 'Oauth2 error: daily request limit reached' } self.assertEqual(loads(obs.body), exp)
def set_token(self, client_id, grant_type, user=None, timeout=3600): """Create access token for the client on redis and send json response Parameters ---------- client_id : str Client that requested the token grant_type : str Type of key being requested user : str, optional If password grant type requested, the user requesting the key. timeout : int, optional The timeout, in seconds, for the token. Default 3600 Returns ------- Writes token information JSON in the form expected by RFC6750: {'access_token': token, 'token_type': 'Bearer', 'expires_in': timeout} access_token: the actual token to use token_type: 'Bearer', which is the expected token type for Oauth2 expires_in: time to token expiration, in seconds. """ token = self.generate_access_token() token_info = { 'timestamp': datetime.datetime.now().strftime('%m-%d-%y %H:%M:%S'), 'client_id': client_id, 'grant_type': grant_type } if user: token_info['user'] = user r_client.hmset(token, token_info) r_client.expire(token, timeout) if grant_type == 'password': # Check if client has access limit key, and if not, create it limit_key = '%s_%s_daily_limit' % (client_id, user) limiter = r_client.get(limit_key) if limiter is None: # Set limit to 5,000 requests per day r_client.setex(limit_key, 86400, 5000) self.write({'access_token': token, 'token_type': 'Bearer', 'expires_in': timeout}) self.finish()
def test_authenticate_header_username(self): obs = self.get('/qiita_db/artifacts/1/', headers={'Authorization': 'Bearer ' + self.user_token}) self.assertEqual(obs.code, 200) # Check rate limiting works self.assertEqual(int(r_client.get(self.user_rate_key)), 1) r_client.setex('[email protected]_daily_limit', 1, 0) obs = self.get('/qiita_db/artifacts/100/', headers={'Authorization': 'Bearer ' + self.user_token}) exp = { 'error': 'invalid_grant', 'error_description': 'Oauth2 error: daily request limit reached' } self.assertEqual(loads(obs.body), exp)
def wrapper(handler, *args, **kwargs): header = handler.request.headers.get('Authorization', None) if header is None: _oauth_error(handler, 'Oauth2 error: invalid access token', 'invalid_request') return token_info = header.split() # Based on RFC6750 if reply is not 2 elements in the format of: # ['Bearer', token] we assume a wrong reply if len(token_info) != 2 or token_info[0] != 'Bearer': _oauth_error(handler, 'Oauth2 error: invalid access token', 'invalid_grant') return token = token_info[1] db_token = r_client.hgetall(token) if not db_token: # token has timed out or never existed _oauth_error(handler, 'Oauth2 error: token has timed out', 'invalid_grant') return # Check daily rate limit for key if password style key if db_token[b'grant_type'] == b'password': limit_key = '%s_%s_daily_limit' % ( db_token[b'client_id'].decode('ascii'), db_token[b'user'].decode('ascii')) limiter = r_client.get(limit_key) if limiter is None: # Set limit to 5,000 requests per day r_client.setex(limit_key, 86400, 5000) else: r_client.decr(limit_key) if int(r_client.get(limit_key)) <= 0: _oauth_error( handler, 'Oauth2 error: daily request limit reached', 'invalid_grant') return return f(handler, *args, **kwargs)
def wrapper(handler, *args, **kwargs): header = handler.request.headers.get('Authorization', None) if header is None: _oauth_error(handler, 'Oauth2 error: invalid access token', 'invalid_request') return token_info = header.split() # Based on RFC6750 if reply is not 2 elements in the format of: # ['Bearer', token] we assume a wrong reply if len(token_info) != 2 or token_info[0] != 'Bearer': _oauth_error(handler, 'Oauth2 error: invalid access token', 'invalid_grant') return token = token_info[1] db_token = r_client.hgetall(token) if not db_token: # token has timed out or never existed _oauth_error(handler, 'Oauth2 error: token has timed out', 'invalid_grant') return # Check daily rate limit for key if password style key if db_token[b'grant_type'] == b'password': limit_key = '%s_%s_daily_limit' % (db_token[b'client_id'].decode( 'ascii'), db_token[b'user'].decode('ascii')) limiter = r_client.get(limit_key) if limiter is None: # Set limit to 5,000 requests per day r_client.setex(limit_key, 86400, 5000) else: r_client.decr(limit_key) if int(r_client.get(limit_key)) <= 0: _oauth_error(handler, 'Oauth2 error: daily request limit reached', 'invalid_grant') return return f(handler, *args, **kwargs)
self.assertEqual(loads(obs.body), exp) def test_authenticate_header_username(self): <<<<<<< HEAD obs = self.get('/qiita_db/artifacts/100/mapping/', headers={ ======= obs = self.get('/qiita_db/artifacts/1/', headers={ >>>>>>> 405cbef0c9f71c620da95a0c1ba6c7d3d588b3ed 'Authorization': 'Bearer ' + self.user_token}) self.assertEqual(obs.code, 200) exp = {'success': False, 'error': 'Artifact does not exist', 'mapping': None} self.assertEqual(loads(obs.body), exp) # Check rate limiting works self.assertEqual(int(r_client.get(self.user_rate_key)), 1) r_client.setex('[email protected]_daily_limit', 0, 2) obs = self.get('/qiita_db/artifacts/100/', headers={ 'Authorization': 'Bearer ' + self.user_token}) exp = {'error': 'invalid_grant', 'error_description': 'Oauth2 error: daily request limit reached' } self.assertEqual(loads(obs.body), exp) def test_authenticate_header_missing(self): obs = self.get('/qiita_db/artifacts/100/') self.assertEqual(obs.code, 400) self.assertEqual(loads(obs.body), { 'error': 'invalid_request', 'error_description': 'Oauth2 error: invalid access token'}) def test_authenticate_header_bad_token(self):