Example #1
0
    def find_env(kls, location, crypto, owner, cache=None):
        """Add environment variables to our environment file"""
        if cache and location in cache:
            return cache[location]

        while True:
            keys, error = EnvironmentFile.loaded_file_from(location, crypto, owner)
            if error:
                quit_choice = "Quit"
                fixed_choice = "I fixed it, try again"
                override_choice = "Override the existing file"
                choice = ask_for_choice("Couldn't read the environment file, what do you want to do?", choices=[quit_choice, fixed_choice, override_choice])
                if choice == quit_choice:
                    raise UserQuit()
                elif choice == fixed_choice:
                    continue
                else:
                    break
            else:
                break

        if not keys:
            keys = EnvironmentFile(location, crypto, owner)

        if cache is not None:
            cache[location] = keys

        return keys
Example #2
0
def configure(repo_name, location, crypto, new_remote=None, version_with=None):
    """Configure a repository"""
    repository = Repository(repo_name, location, crypto)
    if repository.versioned:
        remote = "<none set>"
        if repository.remote:
            remote = repository.remote

        remove_choice = "Stop versioning this directory"
        change_choice = "Change the remote of this directory"
        carryon_choice = "Keep the remote as is"

        if version_with == "nothing":
            choice = remove_choice
        elif new_remote is None and version_with is None:
            choice = ask_for_choice(
                [ "This repo is already versioned\tremote={0}\tlocation={1}".format(remote, repository.location)
                , "What do you want to do?"
                ]
                , [remove_choice, change_choice, carryon_choice]
                )
        else:
            choice = change_choice

        if choice == remove_choice:
            repository.deleteme()
        elif choice == change_choice:
            repository.change_remote(new_remote, remote_type=version_with)
    else:
        change_choice = "Add versioning to this repository"
        carryon_choice = "Keep the repository unversioned"

        if version_with == "nothing":
            log.info("Repository is already unversioned")
        elif version_with is None:
            choice = ask_for_choice(
                [ "This repo is not versioned yet ({0})".format(repository.location)
                , "What do you want to do?"
                ]
                , [carryon_choice, change_choice]
                )
        else:
            choice = change_choice

        if choice == change_choice:
            repository.change_remote(new_remote, remote_type=version_with)
Example #3
0
    def rsaobj_from_location(self, location, only_need_public=False):
        """
        Get us a paramiko.RSAKey from this location

        If the location is a password protected private key and only_need_public then we look for a public key
        If we can't find a public key, then we ask for the password and get the fingerprint that way

        If it isn't a private key, then we raise a credo.NotSSHKey exception
        """
        if only_need_public:
            if location in self._location_to_public_rsaobj:
                return self._location_to_public_rsaobj[location]
        else:
            if location in self._location_to_private_rsaobj:
                return self._location_to_private_rsaobj[location]

        rsaobj = None
        try:
            rsaobj = self.make_rsakey(location, private=True)
            self._location_to_private_rsaobj[location] = rsaobj
        except PasswordRequired:
            if only_need_public:
                pub_key = "{0}.pub".format(location)
                if os.path.exists(pub_key):
                    try:
                        rsaobj = self.make_rsakey(pub_key)
                        self._location_to_public_rsaobj[location] = rsaobj
                    except BadSSHKey as err:
                        log.info("Something wrong with public key %s: %s",
                                 pub_key, err)

        if rsaobj is None:
            while True:
                if only_need_public:
                    log.info(
                        "Couldn't find a public key for password protected private key at %s",
                        location)

                password = get_response(
                    "Password for your private key ({0})".format(location),
                    password=True)

                try:
                    rsaobj = self.make_rsakey(location,
                                              password=password,
                                              private=True)
                    self._location_to_private_rsaobj[location] = rsaobj
                    break
                except BadSSHKey:
                    choice = ask_for_choice(
                        "Couldn't decode the key ({0})".format(location),
                        ["Try again", "Ignore"])
                    if choice == "Ignore":
                        return

        return rsaobj
Example #4
0
def configure(repo_name, location, crypto, new_remote=None, version_with=None):
    """Configure a repository"""
    repository = Repository(repo_name, location, crypto)
    if repository.versioned:
        remote = "<none set>"
        if repository.remote:
            remote = repository.remote

        remove_choice = "Stop versioning this directory"
        change_choice = "Change the remote of this directory"
        carryon_choice = "Keep the remote as is"

        if version_with == "nothing":
            choice = remove_choice
        elif new_remote is None and version_with is None:
            choice = ask_for_choice([
                "This repo is already versioned\tremote={0}\tlocation={1}".
                format(remote, repository.location), "What do you want to do?"
            ], [remove_choice, change_choice, carryon_choice])
        else:
            choice = change_choice

        if choice == remove_choice:
            repository.deleteme()
        elif choice == change_choice:
            repository.change_remote(new_remote, remote_type=version_with)
    else:
        change_choice = "Add versioning to this repository"
        carryon_choice = "Keep the repository unversioned"

        if version_with == "nothing":
            log.info("Repository is already unversioned")
        elif version_with is None:
            choice = ask_for_choice([
                "This repo is not versioned yet ({0})".format(
                    repository.location), "What do you want to do?"
            ], [carryon_choice, change_choice])
        else:
            choice = change_choice

        if choice == change_choice:
            repository.change_remote(new_remote, remote_type=version_with)
Example #5
0
File: git.py Project: cgspeck/credo
    def deleteme(self):
        """Delete the versioning!"""
        quit_choice = "Quit"
        confirm_choice = "Yes I do want to delete!"

        git_folder = os.path.join(self.location, ".git")
        choice = ask_for_choice("Are you sure you want to remove {0}?".format(git_folder), [quit_choice, confirm_choice])
        if choice == quit_choice:
            raise UserQuit()
        else:
            shutil.rmtree(git_folder)
Example #6
0
File: git.py Project: cgspeck/credo
    def resolve_dirty_repo(self):
        """Wait for the user to resolve any changes already in the repo"""
        while True:
            if not self.repo.status():
                break

            quit_choice = "Quit"
            fixed_choice = "I fixed it, please continue"
            choice = ask_for_choice("Seems there is already changes\tlocation={0}".format(self.location), choices=[quit_choice, fixed_choice])
            if choice == quit_choice:
                raise UserQuit()
            elif self.repo.status():
                log.error("Ummm, there's still changes already in the repository...\tlocation=%s", self.location)
Example #7
0
    def rsaobj_from_location(self, location, only_need_public=False):
        """
        Get us a paramiko.RSAKey from this location

        If the location is a password protected private key and only_need_public then we look for a public key
        If we can't find a public key, then we ask for the password and get the fingerprint that way

        If it isn't a private key, then we raise a credo.NotSSHKey exception
        """
        if only_need_public:
            if location in self._location_to_public_rsaobj:
                return self._location_to_public_rsaobj[location]
        else:
            if location in self._location_to_private_rsaobj:
                return self._location_to_private_rsaobj[location]

        rsaobj = None
        try:
            rsaobj = self.make_rsakey(location, private=True)
            self._location_to_private_rsaobj[location] = rsaobj
        except PasswordRequired:
            if only_need_public:
                pub_key = "{0}.pub".format(location)
                if os.path.exists(pub_key):
                    try:
                        rsaobj = self.make_rsakey(pub_key)
                        self._location_to_public_rsaobj[location] = rsaobj
                    except BadSSHKey as err:
                        log.info("Something wrong with public key %s: %s", pub_key, err)

        if rsaobj is None:
            while True:
                if only_need_public:
                    log.info("Couldn't find a public key for password protected private key at %s", location)

                password = get_response("Password for your private key ({0})".format(location), password=True)

                try:
                    rsaobj = self.make_rsakey(location, password=password, private=True)
                    self._location_to_private_rsaobj[location] = rsaobj
                    break
                except BadSSHKey:
                    choice = ask_for_choice("Couldn't decode the key ({0})".format(location), ["Try again", "Ignore"])
                    if choice == "Ignore":
                        return

        return rsaobj
Example #8
0
    def retrieve_public_key_from_disk(self, fingerprint, reason=None):
        """Get this fingerprint and return whether we successfully did so"""
        if self.keys.collection.location_for_fingerprint(fingerprint):
            return True

        def make_ssh_key_location(folders):
            """Get a string to say where we have ssh key folders"""
            if len(self.ssh_key_folders) == 1:
                return self.ssh_key_folders[0]
            else:
                return "one of {0}".format(", ".join(self.ssh_key_folders))

        def add_more_ssh_key_folders():
            """Add more ssh key folders"""
            more_ssh_key_folders = ask_for_ssh_key_folders(
                already_have=self.ssh_key_folders)
            self.ssh_key_folders.extend(more_ssh_key_folders)

        while not self.ssh_key_folders:
            add_more_ssh_key_folders()
        ssh_key_locations = make_ssh_key_location(self.ssh_key_folders)

        while True:
            if self.keys.collection.location_for_fingerprint(fingerprint):
                return True

            ignore_choice = "I don't have this key"
            try_again_choice = "I've added the key to {0}".format(
                ssh_key_locations)
            have_another_ssh_key_folder = "I have another folder with ssh keys in it"
            choice = ask_for_choice(
                "Looking for a public key with fingerprint {0}".format(
                    fingerprint),
                choices=[
                    ignore_choice, try_again_choice,
                    have_another_ssh_key_folder
                ])
            if choice == ignore_choice:
                return False
            elif choice == try_again_choice:
                continue
            elif choice == have_another_ssh_key_folder:
                add_more_ssh_key_folders()
                ssh_key_locations = make_ssh_key_location(self.ssh_key_folders)

            self.keys.find_public_keys()
Example #9
0
    def fix_keys(self, location, error):
        """Get user to fix the keys file"""
        info = {"error": error}
        while True:
            quit_choice = "Quit"
            remove_choice = "Remove the file"
            try_again_choice = "I fixed it, Try again"
            choices = [try_again_choice, remove_choice, quit_choice]
            response = ask_for_choice("Couldn't load {0} as a json file ({1})".format(location, info["error"]), choices)

            if response == quit_choice:
                raise UserQuit()

            elif response == remove_choice:
                os.remove(location)
                return {}

            else:
                try:
                    return json.load(location)
                except ValueError as err:
                    info["error"] = err
Example #10
0
    def retrieve_public_key_from_disk(self, fingerprint, reason=None):
        """Get this fingerprint and return whether we successfully did so"""
        if self.keys.collection.location_for_fingerprint(fingerprint):
            return True

        def make_ssh_key_location(folders):
            """Get a string to say where we have ssh key folders"""
            if len(self.ssh_key_folders) == 1:
                return self.ssh_key_folders[0]
            else:
                return "one of {0}".format(", ".join(self.ssh_key_folders))

        def add_more_ssh_key_folders():
            """Add more ssh key folders"""
            more_ssh_key_folders = ask_for_ssh_key_folders(already_have=self.ssh_key_folders)
            self.ssh_key_folders.extend(more_ssh_key_folders)

        while not self.ssh_key_folders:
            add_more_ssh_key_folders()
        ssh_key_locations = make_ssh_key_location(self.ssh_key_folders)

        while True:
            if self.keys.collection.location_for_fingerprint(fingerprint):
                return True

            ignore_choice = "I don't have this key"
            try_again_choice = "I've added the key to {0}".format(ssh_key_locations)
            have_another_ssh_key_folder = "I have another folder with ssh keys in it"
            choice = ask_for_choice("Looking for a public key with fingerprint {0}".format(fingerprint), choices=[ignore_choice, try_again_choice, have_another_ssh_key_folder])
            if choice == ignore_choice:
                return False
            elif choice == try_again_choice:
                continue
            elif choice == have_another_ssh_key_folder:
                add_more_ssh_key_folders()
                ssh_key_locations = make_ssh_key_location(self.ssh_key_folders)

            self.keys.find_public_keys()
Example #11
0
    def fix_keys(self, location, error):
        """Get user to fix the keys file"""
        info = {"error": error}
        while True:
            quit_choice = "Quit"
            remove_choice = "Remove the file"
            try_again_choice = "I fixed it, Try again"
            choices = [try_again_choice, remove_choice, quit_choice]
            response = ask_for_choice(
                "Couldn't load {0} as a json file ({1})".format(
                    location, info["error"]), choices)

            if response == quit_choice:
                raise UserQuit()

            elif response == remove_choice:
                os.remove(location)
                return {}

            else:
                try:
                    return json.load(location)
                except ValueError as err:
                    info["error"] = err
Example #12
0
def do_import(credo, source=False, half_life=None, **kwargs):
    """Import some creds"""
    typ, info = ask_user_for_secrets(credo, source=source)
    if typ == "amazon":
        access_key, secret_key = info
        iam_pair = IamPair(access_key, secret_key, half_life=half_life)

        if not iam_pair.works:
            raise BadCredential("The credentials you just provided don't work....")
        half_life = normalise_half_life(half_life, access_key) or getattr(credo, "half_life", None)
        iam_pair.set_half_life(half_life)
        iam_pair._changed = False

    elif typ == "saml":
        access_key = None

        # Keep asking for username and password until they give one
        while True:
            idp_username = get_response("Idp username", default=os.environ.get("USER"))
            idp_password = get_response("Idp password", password=True)
            iam_pair = IamSaml(info, idp_username, idp_password, half_life=half_life)
            try:
                arns = iam_pair.arns
            except SamlNotAuthorized:
                continue

            saml_account = ask_for_choice("Which account do you want to use?", choices=sorted(arns, key=lambda a: a.role_arn))
            break
    else:
        raise ProgrammerError("Unknown credential type {0}".format(typ))

    structure, chains = credo.find_credentials(asker=ask_for_choice_or_new, want_new=True)
    creds = list(credo.credentials_from(structure, chains, typ=typ))[0]
    cred_path = creds.credential_path
    log.info("Making credentials for\trepo=%s\taccount=%s\tuser=%s", cred_path.repository.name, cred_path.account.name, cred_path.user.name)

    if typ != "saml":
        cred_path.repository.pub_key_syncer.sync()
        log.debug("Crypto has private keys %s", credo.crypto.private_key_fingerprints)
        log.debug("Crypto has public_keys %s", credo.crypto.public_key_fingerprints)

        if not credo.crypto.can_encrypt:
            raise CantEncrypt("No public keys to encrypt with", repo=cred_path.repository.name)
        if not credo.crypto.can_sign:
            log.error("Couldn't find any private keys matching your known public keys!")
            cred_path.repository.pub_key_syncer.sync(ask_anyway=True)
            if not credo.crypto.can_sign:
                raise CantSign("No private keys with matching public keys to sign with", repo=cred_path.repository.name)

    if typ == "amazon":
        account_id = cred_path.account.account_id(iam_pair=iam_pair)
        if iam_pair.ask_amazon_for_account() != account_id:
            raise BadCredential("The credentials you are importing are for a different account"
                , credentials_account_id=iam_pair.ask_amazon_for_account(), importing_into_account_name=cred_path.account.name, importing_into_account_id=account_id
                )

        username = cred_path.user.username(iam_pair=iam_pair)
        if iam_pair.ask_amazon_for_username() != username:
            raise BadCredential("The credentials you are importing are for a different user"
                , credentials_user=iam_pair.ask_amazon_for_username(), importing_into_user=username
                )

        creds.keys.add(iam_pair)
    else:
        contents = creds.contents
        contents.keys["provider"] = info
        contents.keys["role"] = saml_account.encrypted_values()
        contents.keys["idp_username"] = idp_username

    creds.save(half_life=half_life)
    cred_path.repository.synchronize()
Example #13
0
    def manually_confirm_keys(self, location, contents):
        """Manually confirm the urls and pems in our contents file"""
        result = {"pems": [], "urls": []}
        pems = contents.get("pems", [])
        urls = contents.get("urls", [])

        if pems:
            log.info(
                "You need to confirm that you own the private keys for these public keys"
            )
            fingerprints_with_pems = self.crypto.zip_with_fingerprints(pems)
            print("File contains public keys with these fingerprints",
                  file=sys.stderr)
            print("\t{0}".format("\n\t".join(v[0].decode('utf-8')
                                             for v in fingerprints_with_pems)),
                  file=sys.stderr)

            if self.crypto.private_key_fingerprints:
                print("\nWe know about these private keys", file=sys.stderr)
                print("\t{0}".format("\n\t".join(
                    self.crypto.private_key_fingerprints)),
                      file=sys.stderr)

            matches = all(fingerprint in self.crypto.private_key_fingerprints
                          for fingerprint, _ in fingerprints_with_pems)
            matches_str = " (Not all the public keys match existing private keys)"
            if matches:
                matches_str = " (All the keys match private keys on your computer)"

            quit_choice = "Quit"
            confirm_all_choice = "I say all of them are valid {0}".format(
                matches_str)
            individual_confirm_choice = "I'll confirm them individually"

            if matches:
                confirm_all_choice = "I say all of them are valid (All the keys match private keys on this computer)"
            else:
                individual_confirm_choice = "I'll confirm them individually (Not all the keys match private keys on this computer)"

            choice = ask_for_choice(
                "How do you want to confirm your keys?",
                [quit_choice, confirm_all_choice, individual_confirm_choice])

            if choice == quit_choice:
                raise UserQuit()
            elif choice == confirm_all_choice:
                result["pems"].extend(pems)
            else:
                for fingerprint, pem in fingerprints_with_pems:
                    matches = fingerprint in self.crypto.private_key_fingerprints
                    matches_str = ""
                    if matches:
                        matches_str = " (Matches a private key on this computer)"
                    quit_choice = "Quit"
                    exclude_choice = "No"
                    include_choice = "yes"
                    if matches:
                        include_choice = "Yes{0}".format(matches_str)
                    else:
                        exclude_choice = "No{0}".format(matches_str)

                    choice = ask_for_choice(
                        "Is {0} a fingerprint of yours?".format(fingerprint),
                        [include_choice, exclude_choice, quit_choice])
                    if choice == quit_choice:
                        raise UserQuit()
                    elif choice == include_choice:
                        result["pems"].append(pem)

        if urls:
            log.info("You need to confirm you want keys from these urls")
            print("\t{0}".join("\n\t".join(urls)))

            quit_choice = "Quit"
            confirm_all_choice = "All of them are valid"
            individual_confirm_choice = "I'll confirm them individually"
            choice = ask_for_choice(
                "How do you want to confirm the urls?",
                [quit_choice, confirm_all_choice, individual_confirm_choice])

            if choice == quit_choice:
                raise UserQuit()
            elif confirm_all_choice:
                result["urls"].extend(urls)
            else:
                for url in urls:
                    quit_choice = "Quit"
                    exclude_choice = "No"
                    include_choice = "Yes"
                    choice = ask_for_choice(
                        "Is this urls fine?",
                        [include_choice, exclude_choice, quit_choice])
                    if choice == quit_choice:
                        raise UserQuit()
                    elif choice == include_choice:
                        result["urls"].append(url)

        return result
Example #14
0
    def manually_confirm_keys(self, location, contents):
        """Manually confirm the urls and pems in our contents file"""
        result = {"pems": [], "urls": []}
        pems = contents.get("pems", [])
        urls = contents.get("urls", [])

        if pems:
            log.info("You need to confirm that you own the private keys for these public keys")
            fingerprints_with_pems = self.crypto.zip_with_fingerprints(pems)
            print("File contains public keys with these fingerprints", file=sys.stderr)
            print("\t{0}".format("\n\t".join(v[0] for v in fingerprints_with_pems)), file=sys.stderr)

            if self.crypto.private_key_fingerprints:
                print("\nWe know about these private keys", file=sys.stderr)
                print("\t{0}".format("\n\t".join(self.crypto.private_key_fingerprints)), file=sys.stderr)

            matches = all(fingerprint in self.crypto.private_key_fingerprints for fingerprint, _ in fingerprints_with_pems)
            matches_str = " (Not all the public keys match existing private keys)"
            if matches:
                matches_str = " (All the keys match private keys on your computer)"

            quit_choice = "Quit"
            confirm_all_choice = "I say all of them are valid {0}".format(matches_str)
            individual_confirm_choice = "I'll confirm them individually"

            if matches:
                confirm_all_choice = "I say all of them are valid (All the keys match private keys on this computer)"
            else:
                individual_confirm_choice = "I'll confirm them individually (Not all the keys match private keys on this computer)"

            choice = ask_for_choice("How do you want to confirm your keys?", [quit_choice, confirm_all_choice, individual_confirm_choice])

            if choice == quit_choice:
                raise UserQuit()
            elif choice == confirm_all_choice:
                result["pems"].extend(pems)
            else:
                for fingerprint, pem in fingerprints_with_pems:
                    matches = fingerprint in self.crypto.private_key_fingerprints
                    matches_str = ""
                    if matches:
                        matches_str = " (Matches a private key on this computer)"
                    quit_choice = "Quit"
                    exclude_choice = "No"
                    include_choice = "yes"
                    if matches:
                        include_choice = "Yes{0}".format(matches_str)
                    else:
                        exclude_choice = "No{0}".format(matches_str)

                    choice = ask_for_choice("Is {0} a fingerprint of yours?".format(fingerprint), [include_choice, exclude_choice, quit_choice])
                    if choice == quit_choice:
                        raise UserQuit()
                    elif choice == include_choice:
                        result["pems"].append(pem)

        if urls:
            log.info("You need to confirm you want keys from these urls")
            print("\t{0}".join("\n\t".join(urls)))

            quit_choice = "Quit"
            confirm_all_choice = "All of them are valid"
            individual_confirm_choice = "I'll confirm them individually"
            choice = ask_for_choice("How do you want to confirm the urls?", [quit_choice, confirm_all_choice, individual_confirm_choice])

            if choice == quit_choice:
                raise UserQuit()
            elif confirm_all_choice:
                result["urls"].extend(urls)
            else:
                for url in urls:
                    quit_choice = "Quit"
                    exclude_choice = "No"
                    include_choice = "Yes"
                    choice = ask_for_choice("Is this urls fine?", [include_choice, exclude_choice, quit_choice])
                    if choice == quit_choice:
                        raise UserQuit()
                    elif choice == include_choice:
                        result["urls"].append(url)

        return result
Example #15
0
def do_import(credo, source=False, half_life=None, **kwargs):
    """Import some creds"""
    typ, info = ask_user_for_secrets(credo, source=source)
    if typ == "amazon":
        access_key, secret_key = info
        iam_pair = IamPair(access_key, secret_key, half_life=half_life)

        if not iam_pair.works:
            raise BadCredential(
                "The credentials you just provided don't work....")
        half_life = normalise_half_life(half_life, access_key) or getattr(
            credo, "half_life", None)
        iam_pair.set_half_life(half_life)
        iam_pair._changed = False

    elif typ == "saml":
        access_key = None

        # Keep asking for username and password until they give one
        while True:
            idp_username = get_response("Idp username",
                                        default=os.environ.get("USER"))
            idp_password = get_response("Idp password", password=True)
            iam_pair = IamSaml(info,
                               idp_username,
                               idp_password,
                               half_life=half_life)
            try:
                arns = iam_pair.arns
            except SamlNotAuthorized:
                continue

            saml_account = ask_for_choice("Which account do you want to use?",
                                          choices=sorted(
                                              arns, key=lambda a: a.role_arn))
            break
    else:
        raise ProgrammerError("Unknown credential type {0}".format(typ))

    structure, chains = credo.find_credentials(asker=ask_for_choice_or_new,
                                               want_new=True)
    creds = list(credo.credentials_from(structure, chains, typ=typ))[0]
    cred_path = creds.credential_path
    log.info("Making credentials for\trepo=%s\taccount=%s\tuser=%s",
             cred_path.repository.name, cred_path.account.name,
             cred_path.user.name)

    if typ != "saml":
        cred_path.repository.pub_key_syncer.sync()
        log.debug("Crypto has private keys %s",
                  credo.crypto.private_key_fingerprints)
        log.debug("Crypto has public_keys %s",
                  credo.crypto.public_key_fingerprints)

        if not credo.crypto.can_encrypt:
            raise CantEncrypt("No public keys to encrypt with",
                              repo=cred_path.repository.name)
        if not credo.crypto.can_sign:
            log.error(
                "Couldn't find any private keys matching your known public keys!"
            )
            cred_path.repository.pub_key_syncer.sync(ask_anyway=True)
            if not credo.crypto.can_sign:
                raise CantSign(
                    "No private keys with matching public keys to sign with",
                    repo=cred_path.repository.name)

    if typ == "amazon":
        account_id = cred_path.account.account_id(iam_pair=iam_pair)
        if iam_pair.ask_amazon_for_account() != account_id:
            raise BadCredential(
                "The credentials you are importing are for a different account",
                credentials_account_id=iam_pair.ask_amazon_for_account(),
                importing_into_account_name=cred_path.account.name,
                importing_into_account_id=account_id)

        username = cred_path.user.username(iam_pair=iam_pair)
        if iam_pair.ask_amazon_for_username() != username:
            raise BadCredential(
                "The credentials you are importing are for a different user",
                credentials_user=iam_pair.ask_amazon_for_username(),
                importing_into_user=username)

        creds.keys.add(iam_pair)
    else:
        contents = creds.contents
        contents.keys["provider"] = info
        contents.keys["role"] = saml_account.encrypted_values()
        contents.keys["idp_username"] = idp_username

    creds.save(half_life=half_life)
    cred_path.repository.synchronize()