Package: cred-manage
cred_manage is for managing credentials.Thecred_managepackage contains classes for managing credentials or secrets.The Abstract Base ClassCredContainerBaseis defined inbase_cred_container.py.Subclasses ofCredContainerBaseare called "Credential Containers"There are 3 methods which are intended to be overridden by subclasses.  If not implemented, aNotImplementedErrorwill be raised.  Sometimes this might be perfectly appropriate, and you should catch these exceptions as applicable.These are:get_cred()- Used to get a credential out of a credential container.set_cred()- If implemented, used to set a credential within a credential container.delete_cred()- If implemented, used to delete a credential within a credential container.A Credential container can really be anything that is reasonably responsible to keep credentials, keys, or other secret things inside of.  For example:A Password Manager like Bitwarden or LastpassA Flat File (Containing an API Key, for example) **A Keychain, like that in MacOSCurrently, thecred_managepackage has these Credential Containers implemented (Contributions are welcome!):FlatFileCredContainer- Used to interact with flat files containing passwords or other secret things.  **Please read the warnings below and take them to heart.BitwardenCredContainer- Used to interact withBitwarden Password Manager.A common pattern might be to use aFlatFileCredContainerto manage the context necessary to subsequently log into and interact with a Password Manager tool, like Bitwarden (BitwardenCredContainer) or Lastpass, or a Keychain, which are surely better places to keep sensitive information than flat files.FlatFileCredContainerFirst things first:Never, never, never, EVERcommit passwords or other secrets into version control.Never.DO NOT DO IT!Instead:Write your code such that it references and reads sensitive information from outside of the repository (e.g. A config file containing a path to another file outside of version control).Avoid keeping sensitive information in flat files in the first place.  If you find yourself with more than just a few secrets in flat files, you should probably rethink your design.For cases where you do decide to keep secrets in flat files, be very sure that the machine on which they reside is sufficiently locked down (beyond the scope of this README.md other than to say:  Not exposed to the internet, no superfluous open ports, and login passwords required for all users.)With that warning behind us...FlatFileCredContainerisn't complex at all.  It doesn't do much more than the standard Python library can do to read from and write to a file with a file handle.  One feature that it does implement is that by default, it will be stubborn (this can be overridden) about interacting with files for which the permission bits are too broad, in which case an exception will be raised.FlatFileCredContainermight be a good place to keep API keys, bearer tokens, or anything else that is needed to bootstrap some process or otherwise allow for automation without human interaction.BitwardenCredContainerBitwardenCredContainer is a wrapper around theBitwarden CLI.  It isNOTa wrapper around theBitwarden API, which as far as this author can tell is only available to Enterprise Organization plans.  If you're a user of an Enterprise Organization plan, you'll probably want to interact with he API directly, using the Pythonrequestslibrary, rather than this package.Thus, a prerequisite is that you'll have installed theBitwarden CLIahead of time.BitwardenCredContainercan be instantiated directly but for convenience, a factory function,make_bitwarden_container()is provided.make_bitwarden_container()accepts just a single argument, which is a path to a flat JSON file with the proper context to instantiate the class via the__init__method.  The contents of the file should look like this:{
    "client_id": "<YOUR CLIENT ID HERE>",
    "client_secret": "<YOUR CLIENT SECRET HERE>",
    "scope": "api",
    "grant_type": "client_credentials",
    "email_address": "<you@yourdomain.com HERE, OPTIONALLY.>"
}Note that theemail_addresskey is optional, to suppress a subsequent prompt for your email address.About Vault Items and GUIDsBitwardenCredContaineris a container around your entire Bitwarden vault.  The vault is initially loaded in it's entirety, but all passwords are redacted and replaced with the string<password removed>, in the spirit of paranoia.  Subsequent calls to methods that would return an actual password, make a secondary call to the CLI to retrieve just that password and return the actual value.  Such methods are listed below and do what you think they might based on their names (more context in Docstrings, if needed):get_cred()get_vault_item_by_guid()get_credentials_by_guid()get_username_by_guid()get_password_by_guid()Each of these methods accepts a GUID, which serves as the 'primary key' for the vault item in question.  If you need to find the GUID for a given item, you can instantiate aBitwardenCredContainerobject and invoke theprint_items()method (This will not print passwords).  Alternatively, you can directly invoke theBitwarden CLIusing thebw list itemscommand (Consider piping intojqfor readability) to find the GUID (under theidkey) for any given vault item.About theBW_SESSIONenvironment variable.When logging intoBitwarden via the CLI, a Session Key is returned, which can be exported to the environment variableBW_SESSIONto suppress subsequent prompts for the master password.  When instantiatingBitwardenCredContainer, a check is performed to see if theBW_SESSIONis set.  If it is set (and valid), YOU WILL NOT be prompted for the master password, interactively.  If it is not set, YOU WILL be prompted for the master password for each instantiation.  Depending on your use case, exploit this functionality (or not) as appropriate.  Hint:  Consider the ways in which you might be able to temporarily store this value in aFlatFileCredContainerobject, only to destroy it when you're done.Example Usage.In this example we use aFlatFileCredContainerobject to read the necessary context to instantiate aBitwardenCredContainerobject out of a flat file.  Then, we print the GUIDs and corresponding names of the items from the Bitwarden Vaultfrom cred_manage.flat_file import FlatFileCredContainer
from cred_manage.bitwarden import BitwardenCredContainer
import json

# Instantiate Flat File Credential Container
ff_obj = FlatFileCredContainer(file_path='/.credentials/bw_api.json', allow_broad_permissions=False)

# Read the JSON contents out of the Flat file Credential Container
j = json.loads(ff_obj.read())

# Use those JSON contents to instantiate a Bitwarden Credential Container
bw = BitwardenCredContainer(**j)  #  <-- If environment variable BW_SESSION is set, then no interactive password prompt here.

# Print the GUIDs and corresponding names of vault items
bw.print_items()