Plugin development ------------------ Follow the steps in :ref:`gettingstarted-label` to set up the correct Python environment. There are administrative steps bellow to describe the plugin. After adding some code to the plugin, the directory can be packaged in a ZIP file and uploaded to SPS. Administrative tasks ^^^^^^^^^^^^^^^^^^^^ Update the following files with information correct for your plugin: ``MANIFEST``: plugin name, descriptions, etc. For details consult the *Creating custom Credential Store plugins* developer's guide. ``Pipfile``: describes what additional Python3 PIP packages to package in the eventual plugin and also what packages to use at development time. Note that the Plugin SDK should *not* be listed in the [packages] section, as the Plugin SDK is pre-installed on Safeguard for Privileges Sessions. There are other pre-installed python packages on the system, consult the developer's guide for more information. In most cases the Plugin SDK should *not* be listed in the [dev-packages] section either as it is installed manually as explained in :ref:`gettingstarted-label`. Basic functionality ^^^^^^^^^^^^^^^^^^^ Inherit the Plugin class from :class:`CredentialStorePlugin ` and implement the appropriate user defined functions: :meth:`do_get_password_list()\ `, :meth:`do_get_private_key_list()\ `, :meth:`do_check_in_credential()\ `, :meth:`do_authentication_completed()\ ` or :meth:`do_session_ended()\ `. The expected return values are defined in the technical document *Creating custom Credential Store plugins*. This is a basic example in which the credential store does not rotate passwords, just simply stores them: .. code-block:: python #!/usr/bin/env pluginwrapper3 from safeguard.sessions.plugin import CredentialStorePlugin class Plugin(CredentialStorePlugin): # To set the name that appears at the front of log messages, otherwise it will be "Noname" PLUGIN_NAME="MySuperPlugin" def do_get_password_list(self): # To get a configuration value: config_value = self.plugin_configuration.get('section', 'option') # To log something: self.logger.debug("This is a debug message") # To access connection information session_id = self.connection.session_id # your logic to fetch password based on self.account and self.asset password = ... return {'passwords': [password]} In the next example the credential store does rotate passwords and it will give a checkout identifier to be used for checking in the password later. .. code-block:: python #!/usr/bin/env pluginwrapper3 from safeguard.sessions.plugin import CredentialStorePlugin from safeguard.sessions.plugin.plugin_base import cookie_property class Plugin(CredentialStorePlugin): @cookie_property def checkout_id(self): return None def do_get_password_list(self): # # logic to fetch password and checkout id based on self.account and self.asset and # any other data in self.connection, self.configuration, etc. # self.checkout_id = ... password = ... return {'passwords': [password]} def do_check_in_credential(self): # logic to check in the password using self.checkout_id and/or self.account, self.asset Pre-defined attributes on self ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ On top of attributes defined by :ref:`pluginbase-section-label`, such as :py:attr:`self.plugin_configuration ` and :py:attr:`self.logger ` the following attributes are available in all the above methods, except where otherwise noted: :class:`self.connection ` which is a read-only object to show a record of the SPS connection that is being processed. For example to find out the protocol used in the connection, write ``self.connection.protocol``. Note: only 'session_id' is available in :meth:`do_authentication_completed() \ ` :meth:`do_check_in_credential()\ ` and :meth:`do_session_ended() ` methods. :py:attr:`self.account ` represents the account name. :py:attr:`self.asset ` represents the asset name. Adding to the constructor ^^^^^^^^^^^^^^^^^^^^^^^^^ To enhance the class constructor, one may overload the :meth:`__init__ ` function and add new functionality. Do keep the original call to ``super().__init__`` at the top. Note that the configuration parameter is the raw string representation of the plugin configuration, which will be turned into :py:attr:`self.plugin_configuration ` by the base class. .. code-block:: python #!/usr/bin/env pluginwrapper3 from safeguard.sessions.plugin import CredentialStorePlugin class Plugin(CredentialStorePlugin): def __init__(self, configuration): super().__init__(configuration) # your setup code