def test_chunk_chaining_with_token(): records = Records(salt='hello world') for n in range(36): records.write(id=f"id-{n + 1}", content=f"hello {n + 1}") chunk = records.chunk(token=None) assert chunk.count == 10 assert chunk.token == 'aGVsbG8gd29ybGQxMA==' chunk = records.chunk(token=records._encode_token(-235)) assert chunk.count == 10 assert chunk.token == 'aGVsbG8gd29ybGQxMA==' with py_raises(ValueError) as error: chunk = records.chunk(token='EOF') chunk = records.chunk(token=records._encode_token(235)) assert chunk.count == 0 assert chunk.token == 'EOF' with py_raises(ValueError) as error: chunk = records.chunk(token='azerty') with py_raises(ValueError) as error: chunk = records.chunk(token='12345')
def test_delete_malformed_request(_api): with py_raises(werkzeug.exceptions.BadRequest): _api.delete(id=None) with py_raises(werkzeug.exceptions.NotFound): _api.delete(id='*alien*')
def test_versions_conflict(_api): id = 'versioned-c09' record_version1 = dict(id=id, title='version 1', version='alpha') record_version2 = dict(id=id, title='version 2', version='beta') record_version3 = dict(id=id, title='version 3', version='beta', previous_version='alpha') record_version4 = dict(id=id, title='version 4', version='gamma', previous_version='alpha') record_version5 = dict(id=id, title='version 5', version='delta', previous_version='beta') record_version6 = dict(id=id, title='version 6', version='delta', previous_version='delta') response = _api.put(id=id, payload=record_version1, persona='leader') assert response == ('', 204) with py_raises(werkzeug.exceptions.Conflict): _api.put(id=id, payload=record_version2, persona='leader') response = _api.put(id=id, payload=record_version3, persona='leader') assert response == ('', 204) with py_raises(werkzeug.exceptions.Conflict): _api.put(id=id, payload=record_version4, persona='leader') response = _api.put(id=id, payload=record_version5, persona='leader') assert response == ('', 204) response = _api.put(id=id, payload=record_version6, persona='leader') assert response == ('', 204) response = _api.get(id=id) payload = json.loads(response.get_data().decode()) assert payload['item']['version'] == 'delta' response = _api.delete(id=id, persona='leader') assert response == ('', 204)
def test_put_malformed_request(_api): record = dict(password='******', hobbies='python', record_has_been_loaded=True) with py_raises(werkzeug.exceptions.BadRequest): _api.put(id=None, payload=record) with py_raises(werkzeug.exceptions.NotFound): _api.put(id='*alien*', payload=record)
def test_record_maximum_size(_api): _api.record_maximum_size = 26 with py_raises(werkzeug.exceptions.BadRequest): _api.post(payload={'title': 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'}, persona='leader') with py_raises(werkzeug.exceptions.BadRequest): _api.put(id='fat', payload={'title': 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'}, persona='leader')
def test_decode_bearer(): secret = 'secret' # missing stamp in bearer payload = dict(identity='Alice', persona='persona', salt='salt') bearer = jwt.encode(payload, secret, algorithm='HS256').decode() with py_raises(ValueError) as error: bearers.decode_bearer(secret=secret, bearer=bearer) # missing salt in bearer payload = dict(identity='Alice', persona='persona', stamp='stamp') bearer = jwt.encode(payload, secret, algorithm='HS256').decode() with py_raises(ValueError) as error: bearers.decode_bearer(secret=secret, bearer=bearer)
def test_grant_all(): scopes = ['alpha', 'beta', 'gamma'] items = [ dict(topic='with_list', personas=['a', 'b', 'c']), dict(topic='with_item', persona='a'), ] permissions = Permissions(authorized_scopes=scopes) for scope in scopes: # nothing is authorized assert permissions.authorize(scope, 'a', 'with_list') is False assert permissions.authorize(scope, 'b', 'with_list') is False assert permissions.authorize(scope, 'c', 'with_list') is False assert permissions.authorize(scope, 'x', 'with_list') is False assert permissions.authorize(scope, 'a', 'with_item') is False assert permissions.authorize(scope, 'x', 'with_item') is False for scope in scopes: # set permissions permissions.grant_all(scope, items) for scope in scopes: # some actions are authorized assert permissions.authorize(scope, 'a', 'with_list') is True assert permissions.authorize(scope, 'b', 'with_list') is True assert permissions.authorize(scope, 'c', 'with_list') is True assert permissions.authorize(scope, 'x', 'with_list') is False assert permissions.authorize(scope, 'a', 'with_item') is True assert permissions.authorize(scope, 'x', 'with_item') is False with py_raises(ValueError) as error: permissions.grant_all(scope='*alien*', items=items)
def test_page(_api): pages = 4 _api.store.salt = 'hello world' for n in range(_api.page_size * (pages - 1) + 7): _api.store.write(id=f"id-{n + 1}", content=f"hello {n + 1}") token = None while token != 'EOF': response = _api.page(token=token) chunk = json.loads(response.data.decode()) token = unquote(chunk['next']) if token.startswith('/page/'): token = token[len('/page/'):] pages -= 1 assert pages == 0 with py_raises(werkzeug.exceptions.NotFound): _api.page(token='EOF') response = _api.page(token=_api.store._encode_token(-235)) chunk = json.loads(response.data.decode()) print(chunk) assert len(chunk['items']) == _api.page_size token = unquote(chunk['next']) assert token != 'EOF'
def test_page(_api): pages = 4 _api.page_size = 30 _api.store.salt = 'hello world' for n in range(int(_api.page_size / 6) * (pages - 1) + 7): _api.store.write(e_mail=f"registered+{n + 1}@alfa.com", persona='registered') _api.store.write(e_mail=f"member+{n + 1}@alfa.com", persona='member', password='******') _api.store.write(e_mail=f"leader+{n + 1}@alfa.com", persona='leader', password='******') _api.store.write(e_mail=f"support+{n + 1}@alfa.com", persona='support', password='******') _api.store.write(e_mail=f"robot+{n + 1}@alfa.com", persona='robot', password='******') _api.store.write(e_mail=f"audit+{n + 1}@alfa.com", persona='audit', password='******') response = _api.page(token=None, persona='member') users = json.loads(response.data.decode())['users'] assert len(users) == 15 # 30 - 5 registered - 5 robot response = _api.page(token=None, persona='leader') users = json.loads(response.data.decode())['users'] assert len(users) == 25 # 30 - 5 robot response = _api.page(token=None, persona='support') users = json.loads(response.data.decode())['users'] assert len(users) == _api.page_size response = _api.page(token=None, persona='audit') users = json.loads(response.data.decode())['users'] assert len(users) == 25 # 30 - 5 robot pages = 5 # because we added multiple records in previous loop token = None while token != 'EOF': response = _api.page(token=token, persona='member') chunk = json.loads(response.data.decode()) token = unquote(chunk['next']) if token.startswith('/users/page/'): token = token[len('/users/page/'):] pages -= 1 assert pages == 0 with py_raises(werkzeug.exceptions.NotFound) as error: _api.page(token='EOF', persona='member') response = _api.page(token=_api.store._encode_token(-235), persona='support') chunk = json.loads(response.data.decode()) print(chunk) assert len(chunk['users']) == _api.page_size token = unquote(chunk['next']) assert token != 'EOF'
def test_post_malformed_request(_api): record = dict(password='******', hobbies='python', record_has_been_loaded=True) with py_raises(werkzeug.exceptions.BadRequest): _api.post(payload=record)
def test_post_duplicate_e_mail(_api): record = dict(e_mail='*****@*****.**', password='******', hobbies='python', record_has_been_loaded=True) response = _api.post(payload=record) assert response == ('', 201, {'Location': f"/users/[email protected]"}) with py_raises(werkzeug.exceptions.Conflict): _api.post(payload=record)
def test_record_life_cycle(_api): id = '01234567890-c01' record_version1 = dict(id=id, title='hello world', description='etc.') record_version2 = dict(id=id, title='another title') response = _api.post(payload=record_version1, persona='leader') assert response == ('', 201, {'Location': '/01234567890-c01'}) response = _api.get(id=id) assert response.status_code == 200 payload = json.loads(response.get_data().decode()) record = payload['item'] for key in record_version1.keys(): assert record[key] == record_version1[key] with py_raises(werkzeug.exceptions.BadRequest): _api.put(id=None, payload=record_version2, persona='leader') response = _api.put(id=id, payload=record_version2, persona='leader') assert response == ('', 204) response = _api.get(id=id) assert response.status_code == 200 payload = json.loads(response.get_data().decode()) record = payload['item'] for key in record_version2.keys(): assert record[key] == record_version2[key] for key in record_version1.keys(): assert key in record.keys() response = _api.delete(id=id, persona='leader') assert response == ('', 204) with py_raises(werkzeug.exceptions.NotFound): _api.get(id=id)
def test_record_life_cycle(_api): e_mail = '*****@*****.**' with py_raises(werkzeug.exceptions.Forbidden): # post unknown persona _api.post(payload=dict(e_mail=e_mail, password='******', persona='*alien*'), persona='leader') initial_record = dict(e_mail=e_mail, password='******', hobbies='python', record_has_been_loaded=True) response = _api.post(payload=initial_record) assert response == ('', 201, {'Location': f"/users/{e_mail}"}) with py_raises(werkzeug.exceptions.Forbidden): # put unknown persona _api.put(id=e_mail, payload=dict(persona='*alien*'), persona='leader') response = _api.login( payload=dict(id=e_mail, password='******', hash_password=False)) assert response.status_code == 200 payload = json.loads(response.get_data().decode()) print(payload) assert len(payload.get('bearer', '')) > 5 response = _api.get(id=e_mail, persona='leader') assert response.status_code == 200 payload = json.loads(response.get_data().decode()) record = payload['user'] assert record['id'] == e_mail for key in initial_record.keys(): if key not in ['record_has_been_loaded', 'password']: assert record[key] == initial_record[key] e_mail_2 = '*****@*****.**' updated_record = dict(e_mail=e_mail_2) with py_raises(werkzeug.exceptions.BadRequest): # no id _api.put(id=None, payload=updated_record, persona='leader') response = _api.put(id=e_mail, payload=updated_record, persona='leader') assert response == ('', 204) with py_raises( werkzeug.exceptions.NotFound): # previous record has disappeared _api.get(id=e_mail, persona='leader') response = _api.get(id=e_mail_2, persona='leader') assert response.status_code == 200 payload = json.loads(response.get_data().decode()) record = payload['user'] print(record) assert record['id'] == e_mail_2 print(updated_record) for key in updated_record.keys(): assert record[key] == updated_record[key] for key in initial_record.keys(): if key not in ['record_has_been_loaded', 'password']: assert key in record.keys() response = _api.delete(id=e_mail_2, persona='support') assert response == ('', 204) with py_raises(werkzeug.exceptions.NotFound): _api.get(id=e_mail_2, persona='member')
def test_authenticate_signature(): db = Users() db.write(id='Alice', password='******', persona='support', e_mail='[email protected]') salt = 'salt' stamp = bearers.get_current_stamp() # unknown user with py_raises(ValueError) as error: db.authenticate_signature('Bob', signature='*signature', salt=salt, stamp=stamp) # really need salted call with py_raises(TypeError) as error: db.authenticate_signature('Alice', signature='*signature', stamp=stamp) # really need stamp with py_raises(TypeError) as error: db.authenticate_signature('Alice', signature='*signature', salt=salt) # random credentials does not pass with py_raises(ValueError) as error: db.authenticate_signature('Alice', signature='*signature', salt=salt, stamp=stamp) # password hash does not work, there is a need for real signature with py_raises(ValueError) as error: db.authenticate_signature('Alice', signature='5b49d1280e8517e54daeeb90034334ae', salt=salt, stamp=stamp) # incorrect salt in signature computation blob = bearers.compute_signature(hash='5b49d1280e8517e54daeeb90034334ae', salt='1234', stamp=stamp) with py_raises(ValueError) as error: db.authenticate_signature('Alice', signature=blob, salt=salt, stamp=stamp) # compute correct signature and check it blob = bearers.compute_signature(hash='5b49d1280e8517e54daeeb90034334ae', salt=salt, stamp=stamp) bearer = db.authenticate_signature('Alice', signature=blob, salt=salt, stamp=stamp) assert bearers.decode_bearer(secret=None, bearer=bearer).persona == 'support'
def test_write_with_wrong_persona(): store = Users() with py_raises(ValueError) as error: store.write(id='id', persona='*alien*', password='******', e_mail='[email protected]')