🚧 Add a 'modern' REST API
This commit is contained in:
parent
9c233c0bd1
commit
05cd81c671
2 changed files with 184 additions and 0 deletions
|
@ -217,6 +217,47 @@ def api_handle_password():
|
||||||
return jsonify(link=link, ttl=ttl)
|
return jsonify(link=link, ttl=ttl)
|
||||||
else:
|
else:
|
||||||
abort(500)
|
abort(500)
|
||||||
|
|
||||||
|
@app.route('/api/v2/passwords/', methods=['POST'])
|
||||||
|
def api_v2_set_password():
|
||||||
|
password = request.json.get('password')
|
||||||
|
ttl = int(request.json.get('ttl', DEFAULT_API_TTL))
|
||||||
|
if not password:
|
||||||
|
# Add ProblemDetails expliciting issue with Password and/or TTL
|
||||||
|
abort(400)
|
||||||
|
|
||||||
|
if not isinstance(ttl, int) or ttl > MAX_TTL:
|
||||||
|
else:
|
||||||
|
# Return ProblemDetails expliciting issue
|
||||||
|
abort(400)
|
||||||
|
|
||||||
|
token = set_password(password, ttl)
|
||||||
|
base_url = set_base_url(request)
|
||||||
|
link = base_url + quote_plus(token)
|
||||||
|
return jsonify(link=link, ttl=ttl)
|
||||||
|
|
||||||
|
@app.route('/api/v2/passwords/<password_key>', methods=['HEAD'])
|
||||||
|
def api_v2_check_password():
|
||||||
|
password_key = unquote_plus(password_key)
|
||||||
|
if not password_exists(password_key):
|
||||||
|
# Return NotFound, to indicate that password does not exists (anymore or at all)
|
||||||
|
# With ProblemDetails expliciting issue (just password not found)
|
||||||
|
abort(404)
|
||||||
|
else:
|
||||||
|
# Return OK, to indicate that password still exists
|
||||||
|
abort(200)
|
||||||
|
|
||||||
|
@app.route('/api/v2/passwords/<password_key>', methods=['GET'])
|
||||||
|
def api_v2_retrieve_password():
|
||||||
|
password_key = unquote_plus(password_key)
|
||||||
|
password = get_password(password_key)
|
||||||
|
if not password:
|
||||||
|
# Return NotFound, to indicate that password does not exists (anymore or at all)
|
||||||
|
# With ProblemDetails expliciting issue (just password not found)
|
||||||
|
abort(404)
|
||||||
|
else:
|
||||||
|
# Return OK and the password in JSON message
|
||||||
|
return jsonify(passwork=passwork)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/<password_key>', methods=['GET'])
|
@app.route('/<password_key>', methods=['GET'])
|
||||||
|
|
143
tests.py
143
tests.py
|
@ -201,6 +201,149 @@ class SnapPassRoutesTestCase(TestCase):
|
||||||
frozen_time.move_to("2020-05-22 12:00:00")
|
frozen_time.move_to("2020-05-22 12:00:00")
|
||||||
self.assertIsNone(snappass.get_password(key))
|
self.assertIsNone(snappass.get_password(key))
|
||||||
|
|
||||||
|
def test_set_password_api_v2(self):
|
||||||
|
with freeze_time("2020-05-08 12:00:00") as frozen_time:
|
||||||
|
password = 'my name is my passport. verify me.'
|
||||||
|
rv = self.app.post(
|
||||||
|
'/api/v2/passwords/',
|
||||||
|
headers={'Accept': 'application/json'},
|
||||||
|
json={'password': password, 'ttl': '1209600'},
|
||||||
|
)
|
||||||
|
|
||||||
|
json_content = rv.get_json()
|
||||||
|
key = re.search(r'https://localhost/([^"]+)', json_content['link']).group(1)
|
||||||
|
key = unquote(key)
|
||||||
|
|
||||||
|
frozen_time.move_to("2020-05-22 11:59:59")
|
||||||
|
self.assertEqual(snappass.get_password(key), password)
|
||||||
|
|
||||||
|
frozen_time.move_to("2020-05-22 12:00:00")
|
||||||
|
self.assertIsNone(snappass.get_password(key))
|
||||||
|
|
||||||
|
def test_set_password_api_v2_default_ttl(self):
|
||||||
|
with freeze_time("2020-05-08 12:00:00") as frozen_time:
|
||||||
|
password = 'my name is my passport. verify me.'
|
||||||
|
rv = self.app.post(
|
||||||
|
'/api/set_password/',
|
||||||
|
headers={'Accept': 'application/json'},
|
||||||
|
json={'password': password},
|
||||||
|
)
|
||||||
|
|
||||||
|
json_content = rv.get_json()
|
||||||
|
key = re.search(r'https://localhost/([^"]+)', json_content['link']).group(1)
|
||||||
|
key = unquote(key)
|
||||||
|
|
||||||
|
frozen_time.move_to("2020-05-22 11:59:59")
|
||||||
|
self.assertEqual(snappass.get_password(key), password)
|
||||||
|
|
||||||
|
frozen_time.move_to("2020-05-22 12:00:00")
|
||||||
|
self.assertIsNone(snappass.get_password(key))
|
||||||
|
|
||||||
|
def test_set_password_api_v2_no_password(self):
|
||||||
|
with freeze_time("2020-05-08 12:00:00") as frozen_time:
|
||||||
|
rv = self.app.post(
|
||||||
|
'/api/set_password/',
|
||||||
|
headers={'Accept': 'application/json'},
|
||||||
|
json={'password': None},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(rv.status, 400)
|
||||||
|
|
||||||
|
json_content = rv.get_json()
|
||||||
|
key = re.search(r'https://localhost/([^"]+)', json_content['link']).group(1)
|
||||||
|
key = unquote(key)
|
||||||
|
|
||||||
|
# TODO : Search for ProblemDetails propreties about Password
|
||||||
|
|
||||||
|
def test_set_password_api_v2_too_big_ttl(self):
|
||||||
|
with freeze_time("2020-05-08 12:00:00") as frozen_time:
|
||||||
|
password = 'my name is my passport. verify me.'
|
||||||
|
rv = self.app.post(
|
||||||
|
'/api/v2/passwords/',
|
||||||
|
headers={'Accept': 'application/json'},
|
||||||
|
json={'password': password, 'ttl': '1209600000'},
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(rv.status, 400)
|
||||||
|
|
||||||
|
json_content = rv.get_json()
|
||||||
|
key = re.search(r'https://localhost/([^"]+)', json_content['link']).group(1)
|
||||||
|
key = unquote(key)
|
||||||
|
|
||||||
|
# TODO : Search for ProblemDetails propreties about TTL
|
||||||
|
|
||||||
|
def test_check_password_api_v2(self):
|
||||||
|
with freeze_time("2020-05-08 12:00:00") as frozen_time:
|
||||||
|
password = 'my name is my passport. verify me.'
|
||||||
|
rv = self.app.post(
|
||||||
|
'/api/v2/password/',
|
||||||
|
headers={'Accept': 'application/json'},
|
||||||
|
json={'password': password},
|
||||||
|
)
|
||||||
|
|
||||||
|
json_content = rv.get_json()
|
||||||
|
key = re.search(r'https://localhost/([^"]+)', json_content['link']).group(1)
|
||||||
|
key = unquote(key)
|
||||||
|
|
||||||
|
rvc = self.app.head('/api/v2/password/' + quote(key))
|
||||||
|
self.assertEqual(rv.status, 200)
|
||||||
|
|
||||||
|
def test_check_password_api_v2_bad_keys(self):
|
||||||
|
with freeze_time("2020-05-08 12:00:00") as frozen_time:
|
||||||
|
password = 'my name is my passport. verify me.'
|
||||||
|
rv = self.app.post(
|
||||||
|
'/api/v2/password/',
|
||||||
|
headers={'Accept': 'application/json'},
|
||||||
|
json={'password': password},
|
||||||
|
)
|
||||||
|
|
||||||
|
json_content = rv.get_json()
|
||||||
|
key = re.search(r'https://localhost/([^"]+)', json_content['link']).group(1)
|
||||||
|
key = unquote(key)
|
||||||
|
|
||||||
|
rvc = self.app.head('/api/v2/password/' + quote(key + key))
|
||||||
|
self.assertEqual(rv.status, 404)
|
||||||
|
|
||||||
|
# TODO : Search for ProblemDetails propreties about Password
|
||||||
|
|
||||||
|
def test_retrieve_password_api_v2(self):
|
||||||
|
with freeze_time("2020-05-08 12:00:00") as frozen_time:
|
||||||
|
password = 'my name is my passport. verify me.'
|
||||||
|
rv = self.app.post(
|
||||||
|
'/api/v2/password/',
|
||||||
|
headers={'Accept': 'application/json'},
|
||||||
|
json={'password': password},
|
||||||
|
)
|
||||||
|
|
||||||
|
json_content = rv.get_json()
|
||||||
|
key = re.search(r'https://localhost/([^"]+)', json_content['link']).group(1)
|
||||||
|
key = unquote(key)
|
||||||
|
|
||||||
|
rvc = self.app.get('/api/v2/password/' + quote(key))
|
||||||
|
self.assertEqual(rv.status, 200)
|
||||||
|
|
||||||
|
json_content_retrieved = rvc.get_json()
|
||||||
|
retrieved_password = json_content['password']
|
||||||
|
self.assertEqual(retrieved_password, password)
|
||||||
|
|
||||||
|
def test_retrieve_password_api_v2_bad_keys(self):
|
||||||
|
with freeze_time("2020-05-08 12:00:00") as frozen_time:
|
||||||
|
password = 'my name is my passport. verify me.'
|
||||||
|
rv = self.app.post(
|
||||||
|
'/api/v2/password/',
|
||||||
|
headers={'Accept': 'application/json'},
|
||||||
|
json={'password': password},
|
||||||
|
)
|
||||||
|
|
||||||
|
json_content = rv.get_json()
|
||||||
|
key = re.search(r'https://localhost/([^"]+)', json_content['link']).group(1)
|
||||||
|
key = unquote(key)
|
||||||
|
|
||||||
|
rvc = self.app.head('/api/v2/password/' + quote(key + key))
|
||||||
|
self.assertEqual(rv.status, 404)
|
||||||
|
|
||||||
|
# TODO : Search for ProblemDetails propreties about Password
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
Loading…
Reference in a new issue