def test_composite_credential1(): # basic test of composite credential keyring = MemoryKeyring() cred = _CCred1("name", keyring=keyring) # When queried, does the chain assert_equal(cred(), {'user': '******', 'password': '******'}) # But the "Front" credential is exposed to the user assert_equal(cred.get('user'), 'user1') assert_equal(keyring.get('name', 'user'), 'user1') assert_raises(ValueError, cred.get, 'unknown_field') assert_equal(cred.get('password'), 'password1') assert_equal(keyring.get('name', 'password'), 'password1') # ATM composite credential stores "derived" ones unconditionally in the # keyring as well assert_equal(keyring.get('name:1', 'user'), 'user1_1') assert_equal(keyring.get('name:1', 'password'), 'password1_2') # and now enter new should remove "derived" entries cred.enter_new() assert_equal(keyring.get('name', 'user'), 'user2') assert_equal(keyring.get('name', 'password'), 'password2') assert_equal(keyring.get('name:1', 'user'), None) assert_equal(keyring.get('name:1', 'password'), None) # which would get reevaluated if requested assert_equal(keyring.entries, { 'name:1': {}, 'name': { 'user': '******', 'password': '******' } }) assert_equal(cred(), {'user': '******', 'password': '******'})
def test_cred1_call(): keyring = MemoryKeyring() cred = UserPassword("name", keyring=keyring) # we will set the name but not the password, expecting UI # requesting it assert_equal(keyring.set('name', 'user', 'user1'), None) assert_equal(keyring.get('name', 'user'), 'user1') assert_equal(cred(), {'user': '******', 'password': '******'}) assert_equal(keyring.get('name', 'password'), 'password1')
def test_composite_credential1(): # basic test of composite credential keyring = MemoryKeyring() cred = _CCred1("name", keyring=keyring) # When queried, does the chain assert_equal(cred(), {'user': '******', 'password': '******'}) # But the "Front" credential is exposed to the user assert_equal(cred.get('user'), 'user1') assert_equal(keyring.get('name', 'user'), 'user1') assert_raises(ValueError, cred.get, 'unknown_field') assert_equal(cred.get('password'), 'password1') assert_equal(keyring.get('name', 'password'), 'password1') # ATM composite credential stores "derived" ones unconditionally in the # keyring as well assert_equal(keyring.get('name:1', 'user'), 'user1_1') assert_equal(keyring.get('name:1', 'password'), 'password1_2') # and now enter new should remove "derived" entries cred.enter_new() assert_equal(keyring.get('name', 'user'), 'user2') assert_equal(keyring.get('name', 'password'), 'password2') assert_equal(keyring.get('name:1', 'user'), None) assert_equal(keyring.get('name:1', 'password'), None) # which would get reevaluated if requested assert_equal(keyring.entries, {'name:1': {}, 'name': {'user': '******', 'password': '******'}}) assert_equal(cred(), {'user': '******', 'password': '******'})
def test_cred1_enter_new(): keyring = MemoryKeyring() cred = UserPassword("name", keyring=keyring) assert_false(cred.is_known) assert_equal(cred.enter_new(), None) assert_true(cred.is_known) assert_equal(keyring.get('name', 'user'), 'user1') assert_equal(keyring.get('name', 'password'), 'password1') keyring.delete('name') assert_raises(KeyError, keyring.delete, 'name', 'user') assert_raises(KeyError, keyring.delete, 'name') assert_equal(keyring.get('name', 'user'), None)
def test_cred1_enter_new(): keyring = MemoryKeyring() cred = UserPassword("name", keyring=keyring) assert_false(cred.is_known) assert_equal(cred.enter_new(), None) assert_true(cred.is_known) assert_equal(keyring.get('name', 'user'), 'user1') assert_equal(keyring.get('name', 'password'), 'password1') keyring.delete('name') assert_raises(KeyError, keyring.delete, 'name', 'user') assert_raises(KeyError, keyring.delete, 'name') assert_equal(keyring.get('name', 'user'), None) # Test it blowing up if we provide unknown field with assert_raises(ValueError) as cme: cred.enter_new(username='******') assert_in('field(s): username. Known but not specified: password, user', str(cme.exception)) # Test that if user is provided, it is not asked cred.enter_new(user='******') assert_equal(keyring.get('name', 'user'), 'user2') assert_equal(keyring.get('name', 'password'), 'newpassword')
def test_cred1_call(): keyring = MemoryKeyring() cred = UserPassword("name", keyring=keyring) # we will set the name but not the password, expecting UI # requesting it assert_equal(keyring.set('name', 'user', 'user1'), None) assert_equal(keyring.get('name', 'user'), 'user1') assert_equal(cred(), {'user': '******', 'password': '******'}) assert_equal(keyring.get('name', 'password'), 'password1') # without intervention the same credentials will be reused # in subsequent attempts assert_equal(cred(), {'user': '******', 'password': '******'}) with patch.dict(dlcfg._merged_store, {'datalad.credentials.force-ask': 'yes'}): assert_equal(cred(), {'user': '******', 'password': '******'}) assert_equal(keyring.get('name', 'user'), 'newuser') assert_equal(keyring.get('name', 'password'), 'newpassword')
def _test_expiring_token(outdir): url = "s3://datalad-test0-versioned/1version-removed-recreated.txt" outpath = op.join(outdir, "output") providers = get_test_providers(url, reload=True) downloader = providers.get_provider(url).get_downloader(url) from time import time, sleep from datalad.downloaders.credentials import AWS_S3, CompositeCredential, UserPassword from datalad.support.keyring_ import MemoryKeyring from datalad.tests.utils import ok_file_has_content credential = downloader.credential # AWS_S3('datalad-test-s3') # We will replace credential with a CompositeCredential which will # mint new token after expiration # crap -- duration must be no shorter than 900, i.e. 15 minutes -- # too long to wait for a test! duration = 900 generated = [] def _gen_session_token(_, key_id=None, secret_id=None): from boto.sts.connection import STSConnection sts = STSConnection(aws_access_key_id=key_id, aws_secret_access_key=secret_id) # Note: without force_new=True it will not re-request a token and would # just return old one if not expired yet. Testing below might fail # if not entirely new token = sts.get_session_token(duration=duration, force_new=True) generated.append(token) return dict(key_id=token.access_key, secret_id=token.secret_key, session=token.session_token, expiration=token.expiration) class CustomS3(CompositeCredential): _CREDENTIAL_CLASSES = (UserPassword, AWS_S3) _CREDENTIAL_ADAPTERS = (_gen_session_token,) keyring = MemoryKeyring() downloader.credential = new_credential = CustomS3("testexpire", keyring=keyring) # but reuse our existing credential for the first part: downloader.credential._credentials[0] = credential # now downloader must use the token generator assert not generated # since we have not called it yet # do it twice so we reuse session and test that we do not # re-mint a new token t0 = time() # not exactly when we generated, might be a bit racy? for i in range(2): downloader.download(url, outpath) ok_file_has_content(outpath, "version1") os.unlink(outpath) # but we should have asked for a new token only once assert len(generated) == 1 assert downloader.credential is new_credential # we did not reset it # sleep for a while and now do a number of downloads during which # token should get refreshed etc # -3 since we have offset -2 hardcoded to refresh a bit ahead of time to_sleep = duration - (time() - t0) - 3 print("Sleeping for %d seconds. Token should expire at %s" % (to_sleep, generated[0].expiration)) sleep(to_sleep) for i in range(5): # should have not been regenerated yet # -2 is our hardcoded buffer if time() - t0 < duration - 2: assert len(generated) == 1 downloader.download(url, outpath) ok_file_has_content(outpath, "version1") os.unlink(outpath) sleep(1) assert len(generated) == 2