🚧 Add a 'modern' REST API

This commit is contained in:
Emilien GUILMINEAU 2024-03-29 11:46:56 +01:00 committed by GitHub
parent 9c233c0bd1
commit 05cd81c671
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 184 additions and 0 deletions

View file

@ -218,6 +218,47 @@ def api_handle_password():
else:
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'])
def preview_password(password_key):

143
tests.py
View file

@ -201,6 +201,149 @@ class SnapPassRoutesTestCase(TestCase):
frozen_time.move_to("2020-05-22 12:00:00")
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__':
unittest.main()