def test_generate_key_profiles(): if not pterm.HAS_SECURITY: pytest.skip("Unable to find security binary") creds = tempfile.NamedTemporaryFile('w', delete=False) print( """User name,Password,Access key ID,Secret access key,Console login link admin,,AKIxxxxxxxxxxxxxxxNS,YiiKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1ULY,h""", file=creds) creds.close() try: security('delete-generic-password', '-a', os.getenv("USER"), '-s', cache()) security('delete-generic-password', '-a', os.getenv("USER"), '-s', aws_key_name(None, None)) except: pass pterm.aws_key_name = aws_key_name pterm.cache = cache pterm.account_aliases = account_aliases res = generate_key_profiles(creds.name, "login.keychain-db") assert res[0]['Name'] == aws_key_name(None, None) # ensure the cache item is picked up if we run the function without a creds file res = generate_key_profiles(None, "login.keychain-db") assert res[0]['Name'] == aws_key_name(None, None)
def rm(name): try: sh.security( "delete-generic-password", a=getpass.getuser(), s=f"{MACOS_KEYCHAIN_PREFIX}: {name}", ) except sh.ErrorReturnCode_44: pass
def add(*, name: str, value: str): out = io.StringIO() sh.security( "add-generic-password", a=getpass.getuser(), s=f"{MACOS_KEYCHAIN_PREFIX}: {name}", w=value, _out=out, ) return out.getvalue()
def security_store(access_key, secret_key, keychain, cache): """Store the AWS credentials in the macOS keychain. An entry is also added in the cache keychain entry, see security_add_to_list. """ name = aws_key_name(access_key, secret_key) data = f"AWS_ACCESS_KEY_ID={access_key} AWS_SECRET_KEY_ID={secret_key}" existing_key = security_find(name) if existing_key == data: return name security('add-generic-password', '-a', os.getenv("USER"), '-s', name, '-w', data, keychain) security_add_to_list(name, keychain, cache) return name
def security_find(name): """Find a macOS keychain item with given name. Returns None if nothing is found. """ try: return str( security('find-generic-password', '-a', os.getenv("USER"), '-s', name, '-w')).rstrip() except sh.ErrorReturnCode_44: # pylint: disable=no-member return None
def security_add_to_list(name, keychain, cache): """Add a key in the keychain cache. MacOS doesnt allow to list all the secrets so a list is maintaind for pterm to allow adding all profiles that were created via cmd line """ data = security_find(cache) if data is not None: security('delete-generic-password', '-a', os.getenv("USER"), '-s', cache) data = json.loads(data) else: data = [] data += [name] security('add-generic-password', '-a', os.getenv("USER"), '-s', cache, '-w', json.dumps(data), keychain) return data
def ls(): out = io.StringIO() sh.awk( sh.grep(sh.security("dump-keychain"), "0x00000007"), "-F=", "{print $2}", _out=out, ) return [ n.split(f'"{MACOS_KEYCHAIN_PREFIX}: ')[1][:-1] for n in out.getvalue().strip().split("\n") if n.startswith(f'"{MACOS_KEYCHAIN_PREFIX}: ') ]