diff --git a/docs/conf.py b/docs/conf.py index 6a6f33c..1f23832 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -17,7 +17,7 @@ # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information project = "Patcher" -copyright = "2024, Andrew Speciale & Chris Ball" +copyright = "2024, Andrew Lerman & Chris Ball" author = "Andrew Speciale & Chris Ball" version = __version__ @@ -119,6 +119,7 @@ "secondary_sidebar_items": { "**/*": ["page-toc", "sourcelink"], }, + "show_toc_level": 3, } # Remove primary sidebar from contributing page diff --git a/docs/reference/api_client.rst b/docs/reference/api_client.rst index 25ad222..dc95bb5 100644 --- a/docs/reference/api_client.rst +++ b/docs/reference/api_client.rst @@ -4,10 +4,5 @@ API Client ========== -.. dropdown:: Summary - :icon: archive - - The ``ApiClient`` is responsible for *most* API calls. Exceptions to this are any API calls interacting with AccessTokens, and calls made during the initial Setup. - .. autoclass:: patcher.client.api_client.ApiClient :members: diff --git a/docs/reference/base_api_client.rst b/docs/reference/base_api_client.rst new file mode 100644 index 0000000..f70b605 --- /dev/null +++ b/docs/reference/base_api_client.rst @@ -0,0 +1,10 @@ +:html_theme.sidebar_secondary.remove: True + +.. _base_api_client: + +=============== +Base API Client +=============== + +.. autoclass:: patcher.client.__init__.BaseAPIClient + :members: diff --git a/docs/reference/decorators.rst b/docs/reference/decorators.rst new file mode 100644 index 0000000..2a3c226 --- /dev/null +++ b/docs/reference/decorators.rst @@ -0,0 +1,9 @@ +:html_theme.sidebar_secondary.remove: True + +========== +Decorators +========== + +.. automodule:: patcher.utils.decorators + :members: + :undoc-members: diff --git a/docs/reference/index.md b/docs/reference/index.md index 8a450af..99fb182 100644 --- a/docs/reference/index.md +++ b/docs/reference/index.md @@ -7,6 +7,7 @@ html_theme.sidebar_secondary.remove: True ```{toctree} :caption: Client Modules +base_api_client api_client config_manager report_manager @@ -34,9 +35,9 @@ token :caption: Utilities animation +decorators exceptions logger -wrappers ``` ```{toctree} diff --git a/docs/reference/wrappers.rst b/docs/reference/wrappers.rst deleted file mode 100644 index a2e2b42..0000000 --- a/docs/reference/wrappers.rst +++ /dev/null @@ -1,13 +0,0 @@ -:html_theme.sidebar_secondary.remove: True - -======== -Wrappers -======== - -.. note:: - - We are planning to refactor the ``check_token`` function into the :mod:`~patcher.client.token_manager` class as it is more suitable for that scope. - -.. automodule:: patcher.utils.wrappers - :members: - :undoc-members: diff --git a/docs/user/customize_reports.rst b/docs/user/customize_reports.rst index 51e8ac6..706bdd0 100644 --- a/docs/user/customize_reports.rst +++ b/docs/user/customize_reports.rst @@ -1,14 +1,14 @@ .. _customize_reports: -===================== +==================== Customizing Reports -===================== +==================== Tailor the user interface elements of your exported PDF reports. You have the flexibility to modify the font, and customize the header and footer text according to your preferences. See the sample PDF image below for an illustration of these customizable features. .. _example-pdf-image: -.. image:: https://raw.githubusercontent.com/liquidz00/Patcher/develop/images/example_pdf.jpeg +.. image:: ../_static/example_pdf.jpeg :alt: Example PDF :width: 750px :align: center @@ -16,71 +16,103 @@ Tailor the user interface elements of your exported PDF reports. You have the fl .. seealso:: Configuring the date format is done at runtime by using the ``--date-format`` option. See :ref:`date format ` for more information. -.. _config_ini: +.. _property_list_file: Setup ------ +===== -When you first launch Patcher, a :ref:`setup assistant ` will automatically create the necessary ``config.ini`` file and copy the required fonts to the appropriate directory. +When you first launch Patcher, a :ref:`setup assistant ` will automatically create the necessary ``com.liquidzoo.patcher.plist`` file in the user's Library Application Support directory, located at ``$HOME/Library/Application Support/Patcher``. Once setup is completed successfully, the ``first_run_done`` key in the property list file will automatically be set to ``True``: -Modifying the file -^^^^^^^^^^^^^^^^^^ +.. code-block:: xml -Any resource Patcher interacts with can be found in the Application Support directory in the user library. Using ``jappleseed`` as an example, the path to the configuration file would be ``'/Users/jappleseed/Library/Application Support/Patcher/config.ini'``. + + + + + Setup + + first_run_done + + + + -Open this file in your text editor of choice, or execute the command below in Terminal to open the file in the TextEdit app. +.. admonition:: Warning + :class: warning -.. code-block:: console + **Do not modify** the ``first_run_done`` key in the ``Setup`` dictionary directly. Altering this key may cause Patcher to re-run the setup process. If you need to reset the initial setup state, use the ``--reset`` option instead. For more information, see :ref:`resetting Patcher `. - $ open -a "TextEdit.app" ~/Library/Application\ Support/Patcher/config.ini +Modifying the Property List File +================================ -Sample configuration -^^^^^^^^^^^^^^^^^^^^ +The property list file contains the settings that control the appearance of the PDF reports. You can edit these values using ``/usr/libexec/PlistBuddy`` or a code editor of your choice (VSCode, BBEdit, CodeRunner, etc.). -Still assuming the logged in user is jappleseed, a ``config.ini`` file could look like the following: +.. admonition:: Opening Property Lists in Xcode + :class: tip -.. code-block:: ini + If the plist file appears as a binary file when opened in VSCode or other editors, you can open it in **Xcode** instead. Xcode is available as a free download from the Mac App Store and fully supports editing plist files. This will prevent issues with binary formatting that some editors may encounter. - [Settings] - patcher_path = /Users/jappleseed/Library/Application Support/Patcher +Using ``jappleseed`` as an example, the path to the property list file would be: - [UI] - header_text = AnyOrg Mac Patch Report - footer_text = AnyOrg Mac Patch Report - font_name = Assistant - font_regular_path = /Users/jappleseed/Library/Application Support/Patcher/fonts/Assistant-Regular.ttf - font_bold_path = /Users/jappleseed/Library/Application Support/Patcher/fonts/Assistant-Bold.ttf +``/Users/jappleseed/Library/Application Support/Patcher/com.liquidzoo.patcher.plist`` -The above example would result in a PDF report that looks identical to the :ref:`example PDF image ` at the top of this page. +Editing the Header & Footer Text +-------------------------------- -.. warning:: - Altering the ``[Settings]`` section of the configuration file is not recommended. Patcher references this path throughout the codebase and modifying it incorrectly may lead to unintended results or errors. +.. tip:: + Why not use ``defaults`` to edit the property list file? Unfortunately, the ``defaults`` binary in macOS lacks the ability to update keys nested within dictionaries. ``PlistBuddy`` is much better equipped to handle property lists with nested elements. -Edit Header and Footer Text ---------------------------- +To modify the header and footer text using PlistBuddy, use the following commands: -To customize the header and footer texts, simply modify the ``header_text`` and ``footer_text`` values under the UI section of the config file. +.. code-block:: console -.. code-block:: ini + $ /usr/libexec/PlistBuddy -c "Set :UI:HEADER_TEXT 'Your Custom Header Text'" ~/Library/Application\ Support/Patcher/com.liquidzoo.patcher.plist + $ /usr/libexec/PlistBuddy -c "Set :UI:FOOTER_TEXT 'Your Custom Footer Text'" ~/Library/Application\ Support/Patcher/com.liquidzoo.patcher.plist - [UI] - header_text = Your Custom Header Text - footer_text = Your Custom Footer Text +These commands will correctly update the ``HEADER_TEXT`` and ``FOOTER_TEXT`` keys within the ``UI`` dictionary. .. note:: The footer text will automatically append a ``|`` character followed by the page number to the end of the specified footer text. +Sample Property List Structure +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Below is an example of what the nested UI dictionary might look like in the property list file: + +.. code-block:: xml + + + + + + UI + + HEADER_TEXT + AnyOrg Patch Report + FOOTER_TEXT + AnyOrg Patch Report + FONT_NAME + Assistant + FONT_REGULAR_PATH + /Users/jappleseed/Library/Application Support/Patcher/fonts/Assistant-Regular.ttf + FONT_BOLD_PATH + /Users/jappleseed/Library/Application Support/Patcher/fonts/Assistant-Bold.ttf + + + + +The above example would result in a PDF report that looks identical to the :ref:`example PDF image ` at the top of this page. + Customizing the Font -------------------- -If you wish to change the font, modify the ``font_name``, ``font_regular_path`` and ``font_bold_path`` values in the UI section: +To change the font, update the ``FONT_NAME``, ``FONT_REGULAR_PATH`` and ``FONT_BOLD_PATH`` values in the UI dictionary. -.. code-block:: ini +.. code-block:: console - [UI] - font_name = YourPreferredFont - font_regular_path = /path/to/your/font/Regular.ttf - font_bold_path = /path/to/your/font/Bold.ttf + $ /usr/libexec/PlistBuddy -c "Set :UI:FONT_NAME 'Helvetica'" ~/Library/Application\ Support/Patcher/com.liquidzoo.patcher.plist + $ /usr/libexec/PlistBuddy -c "Set :UI:FONT_REGULAR_PATH '/path/to/Helvetica-Regular.ttf'" ~/Library/Application\ Support/Patcher/com.liquidzoo.patcher.plist + $ /usr/libexec/PlistBuddy -c "Set :UI:FONT_BOLD_PATH '/path/to/Helvetica-Bold.ttf'" ~/Library/Application\ Support/Patcher/com.liquidzoo.patcher.plist .. important:: The default font used in testing is `Google's Assistant Font `_. While you can specify a different font to match your organization's branding, be aware that doing so may cause formatting or alignment issues in the exported PDF reports. It is recommended to test the PDF export functionality thoroughly after changing the font to ensure the new font does not adversely affect the document's appearance. @@ -88,16 +120,31 @@ If you wish to change the font, modify the ``font_name``, ``font_regular_path`` Full Example Configuration -------------------------- -A full example configuration with custom header, footer text and a specified font: - -.. code-block:: ini - - [Settings] - patcher_path = /Users/$user/Library/Application Support/Patcher - - [UI] - header_text = Confidential Report - footer_text = © 2024 Your Company - font_name = Helvetica - font_regular_path = /path/to/Helvetica-Regular.ttf - font_bold_path = /path/to/Helvetica-Bold.ttf +Here is an example configuration with custom header, footer text, and a specified font: + +.. code-block:: xml + + + + + + Setup + + first_run_done + + + UI + + HEADER_TEXT + Confidential Report + FOOTER_TEXT + © 2024 Your Company + FONT_NAME + Helvetica + FONT_REGULAR_PATH + /path/to/Helvetica-Regular.ttf + FONT_BOLD_PATH + /path/to/Helvetica-Bold.ttf + + + diff --git a/docs/user/install.md b/docs/user/install.md index a98881b..f5498d1 100644 --- a/docs/user/install.md +++ b/docs/user/install.md @@ -59,69 +59,16 @@ Options: ``` (ssl-verify)= -## SSL Verification and Self-Signed Certificates +## SSL Verification -When using Patcher, you may encounter SSL verification issues, particularly if your network environment uses self-signed certificates or custom Certificate Authorities (CAs). Patcher uses both the `aiohttp` and `urllib` libraries to make API calls. +As of version 1.4.1, Patcher no longer modifies SSL configurations. SSL handling for custom certificates required some additional TLC by end users and would often cause SSL verification errors at runtime. This is compounded when taking into account our end users are likely on managed systems with security policies and third-party certificates (e.g., Zscaler). -:::{versionadded} 1.3.5 -A certificate file can be passed to Patcher with the `--custom-ca-file` option. -See {ref}`custom-ca` for more information. -::: - -### Configure macOS to Trust Custom Certificates - -If you are on a managed host, chances are this has already been done for you as part of being enrolled with an MDM. However, it never hurts to verify. - -1. Open the Keychain application in `/Applications/Utilities/Keychain Access.app` -2. Click **System** on the left sidebar underneath *System Keychains*, and select the **Certificates** tab -3. Locate the Certificate in question and double-click to open it -4. Set the certificate to "Always Trust" under the Trust section - -#### Exporting the Certificate - -Alternatively, you may need to export the certificate in `.pem` format. If so, export the certificate from Keychain by right-clicking and selecting **Export** from the dialog menu. Be sure to select the file format as `.pem` when exporting. - -### Adding Custom Certificates +With the current version, SSL handling is no longer required by the end user. We've integrated ``curl`` with ``asyncio`` within Patcher's functionality to automatically handle SSL verification as part of API requests. This design choice removes the need for manual SSL configurations, streamlining the setup for MacAdmins on managed computers. -Patcher uses both `aiohttp` and `urllib` to make API requests. Both libraries rely on Python's built-in `ssl` module to handle SSL certificates. On macOS, Python *typically* uses the system's SSL certificate store or the certificates bundled with Python itself. - -:::{attention} -The following steps will likely need local administrator privileges (`sudo`). -::: - -#### Identify the Certificate Path - -First, determine where Python is currently looking for certificates. You can find this by using the `ssl` module in Python. - -::::{tab-set} - -:::{tab-item} Command Prompt -```console -$ python3 -c "import ssl; print(ssl.get_default_verify_paths())" -``` -::: - -:::{tab-item} Python -```python -import ssl - -# Print default SSL certificate paths -print(ssl.get_default_verify_paths()) -``` +:::{note} +While the current integration between `curl` and `asyncio` gets the job done for handling SSL verification, there's room for refinement. Community contributions to enhance this functionality are welcome and encouraged. If you're interested in exploring ways to solidify this process further, check out the relevant code in the {ref}`BaseAPIClient ` class. ::: -:::: - -The command will output paths where Python looks for certificates, usually pointing to a `cert.pem` file or similar. Be sure to notate the proper path before proceeding. - -#### Add the Self-Signed Certificate - -If not completed already, [export](#exporting-the-certificate) the certificate to a file location of your choosing. The certificate can then be added to the default bundle with the following command: - -```console -$ cat /path/to/exported/certificate.pem >> /path/to/default/certificate/location/cert.pem -``` - -If permission errors are thrown, attempt the command again with `sudo`. +This update makes it easier for Patcher to run smoothly in secure environments, without the hassle of adjusting system certificates or tinkering with Python’s SSL settings. **If none of the above steps worked to resolve the issue**, please reach out to us and let us know what (if any) security software is installed on your machine. This will help us troubleshoot issues in the future. Additionally, get in touch with someone from your security team for next steps as they may have a solution in place. diff --git a/docs/user/prereqs.md b/docs/user/prereqs.md index 8ab0471..7e6f193 100644 --- a/docs/user/prereqs.md +++ b/docs/user/prereqs.md @@ -5,10 +5,8 @@ Ensure you have the following before proceeding with the installation and setup - **Python 3.10 or Higher**: Make sure Python is installed on your system. You can download it from [python.org](https://www.python.org/downloads/). - **Access to a Jamf Pro Instance**: You need an instance of Jamf Pro with administrator privileges to perform setup tasks. -:::{important} -**For versions 1.3.4 and later**: Patcher can automatically handle the creation of API clients and roles, provided [SSO is not used for Jamf Pro accounts](https://developer.jamf.com/jamf-pro/docs/jamf-pro-api-overview#authentication-and-authorization). - -If SSO is used, you can either manually create an API Role & Client, *or* you can create a standard user account with admin privileges to pass to the setup assistant. +:::{versionadded} 1.3.5 +Patcher can automatically handle the creation of API clients and roles, provided [SSO is not used for Jamf Pro accounts](https://developer.jamf.com/jamf-pro/docs/jamf-pro-api-overview#authentication-and-authorization). If SSO is used, you can either manually create an API Role & Client, *or* you can create a standard user account with admin privileges to pass to the setup assistant. ::: ## Handling SSO in Jamf Pro @@ -37,7 +35,5 @@ If your Jamf Pro environment uses Single Sign-On (SSO), follow the instructions - After setup has completed, delete the temporary account to maintain security standards. :::{seealso} -:class: dropdown - Refer to the [Jamf Pro Documentation](https://learn.jamf.com/bundle/jamf-pro-documentation-current/page/API_Roles_and_Clients.html) on API Roles and Clients for more information on creating roles and clients. ::: diff --git a/docs/user/usage.rst b/docs/user/usage.rst index bca1dfc..d89b897 100644 --- a/docs/user/usage.rst +++ b/docs/user/usage.rst @@ -114,6 +114,8 @@ The ``--concurrency`` option sets the *maximum* number of concurrent API request $ patcherctl --path '/path/to/save' --concurrency 10 +.. _resetting_patcher: + Reset ----- @@ -126,19 +128,18 @@ To streamline the customization process, you can use the ``--reset`` flag with P $ patcherctl --reset -.. _custom-ca: Custom CA File -------------- +.. admonition:: Removed in version 1.4.1 + :class: danger + + The ``--custom-ca-file`` flag has been removed entirely. CA file handling is now automatic via ``curl``. + Pass a path to a ``.pem`` certificate to use as the default `SSL context `_. Can be useful if running into SSL Validation Errors when using Patcher. .. code-block:: console $ patcherctl --custom-ca-file '/path/to/.pem/file' -.. seealso:: - :class: dropdown - - :ref:`ssl-verify` on the installation page -