Skip to content
This repository has been archived by the owner on Feb 14, 2025. It is now read-only.

Commit

Permalink
Add metadata_only flag to GET /v1/credentials/<ID>
Browse files Browse the repository at this point in the history
  • Loading branch information
irhkang committed Mar 19, 2020
1 parent 4caa493 commit 8277eb9
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 6 deletions.
4 changes: 2 additions & 2 deletions confidant/models/credential.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,11 @@ def next_rotation_date(self):
# If a credential has never been rotated or been decrypted,
# immediately rotate
if self.last_rotation_date is None:
return datetime.utcnow()
return datetime.now()

if (self.last_decrypted_date and
self.last_decrypted_date > self.last_rotation_date):
return datetime.utcnow()
return self.last_decrypted_date

days = settings.MAXIMUM_ROTATION_DAYS
for tag in self.tags:
Expand Down
19 changes: 16 additions & 3 deletions confidant/routes/credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import re
import uuid

from datetime import datetime
from flask import blueprints, jsonify, request
from pynamodb.exceptions import DoesNotExist, PutError

Expand Down Expand Up @@ -156,6 +157,12 @@ def get_credential(id):
the provided ID.
:statuscode 404: The provided credential ID does not exist.
"""
metadata_only = request.args.get(
'metadata_only',
default=False,
type=bool,
)

if not acl_module_check(resource_type='credential',
action='metadata',
resource_id=id):
Expand Down Expand Up @@ -187,16 +194,22 @@ def get_credential(id):
),
}
include_credential_pairs = False
if acl_module_check(resource_type='credential',
action='get',
resource_id=id):
if not metadata_only and acl_module_check(resource_type='credential',
action='get',
resource_id=id):
permissions['get'] = True
include_credential_pairs = True

if settings.ENABLE_SAVE_LAST_DECRYPTION_TIME:
credential.last_decrypted_date = datetime.now()
credential.save()

log_line = "{0} get credential {1}".format(
authnz.get_logged_in_user(),
id
)
logger.info(log_line)

credential_response = CredentialResponse.from_credential(
credential,
include_credential_keys=True,
Expand Down
6 changes: 6 additions & 0 deletions confidant/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,12 @@ def str_env(var_name, default=''):
# be rotated
ROTATION_DAYS_CONFIG = json.loads(str_env('ROTATION_DAYS_CONFIG', '{}'))

# If this is eanbled, update credential.last_decrypted_date
# when credential.credential_pairs is sent back to the client
# in GET /v1/credentials/<ID> to keep track of when a human
# last saw a credential pair
ENABLE_SAVE_LAST_DECRYPTION_TIME = bool_env('ENABLE_SAVE_LAST_DECRYPT_TIME')


# Configuration validation
_settings_failures = False
Expand Down
22 changes: 21 additions & 1 deletion tests/unit/confidant/routes/credentials_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ def test_get_credential(mocker, credential):
app = create_app()

mocker.patch('confidant.settings.USE_AUTH', False)
mocker.patch('confidant.settings.ENABLE_SAVE_LAST_DECRYPTION_TIME', True)
mock_save = mocker.patch.object(Credential, 'save', return_value=None)
mocker.patch(
'confidant.routes.credentials.authnz.get_logged_in_user',
return_value='test@example.com',
Expand Down Expand Up @@ -155,11 +157,29 @@ def acl_module_check(resource_type, action, resource_id):
ret = app.test_client().get('/v1/credentials/5678', follow_redirects=False)
assert ret.status_code == 403

# Make sure credential is saved when ENABLE_SAVE_LAST_DECRYPTION_TIME=True
# and metadata_only=False
credential.id = '9012'
ret = app.test_client().get('/v1/credentials/3456', follow_redirects=False)
ret = app.test_client().get(
'/v1/credentials/3456?metadata_only=false',
follow_redirects=False
)
json_data = json.loads(ret.data)
assert ret.status_code == 200
assert json_data['permissions']['update'] is True
assert mock_save.call_count == 1

# Make sure credential is NOT saved when
# ENABLE_SAVE_LAST_DECRYPTION_TIME=True and metadata_only=True
mock_save = mocker.patch.object(Credential, 'save', return_value=None)
ret = app.test_client().get(
'/v1/credentials/3456?metadata_only=true',
follow_redirects=False
)
json_data = json.loads(ret.data)
assert ret.status_code == 200
assert json_data['permissions']['update'] is True
assert mock_save.call_count == 0

mocker.patch(
'confidant.routes.credentials.Credential.get',
Expand Down

0 comments on commit 8277eb9

Please # to comment.