Skip to content

Commit

Permalink
Update project docs with 1.4.1 changes
Browse files Browse the repository at this point in the history
  • Loading branch information
liquidz00 committed Nov 7, 2024
1 parent 835773c commit 4d43ed2
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 144 deletions.
3 changes: 2 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__
Expand Down Expand Up @@ -119,6 +119,7 @@
"secondary_sidebar_items": {
"**/*": ["page-toc", "sourcelink"],
},
"show_toc_level": 3,
}

# Remove primary sidebar from contributing page
Expand Down
5 changes: 0 additions & 5 deletions docs/reference/api_client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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:
10 changes: 10 additions & 0 deletions docs/reference/base_api_client.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
:html_theme.sidebar_secondary.remove: True

.. _base_api_client:

===============
Base API Client
===============

.. autoclass:: patcher.client.__init__.BaseAPIClient
:members:
9 changes: 9 additions & 0 deletions docs/reference/decorators.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
:html_theme.sidebar_secondary.remove: True

==========
Decorators
==========

.. automodule:: patcher.utils.decorators
:members:
:undoc-members:
3 changes: 2 additions & 1 deletion docs/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ html_theme.sidebar_secondary.remove: True
```{toctree}
:caption: Client Modules
base_api_client
api_client
config_manager
report_manager
Expand Down Expand Up @@ -34,9 +35,9 @@ token
:caption: Utilities
animation
decorators
exceptions
logger
wrappers
```

```{toctree}
Expand Down
13 changes: 0 additions & 13 deletions docs/reference/wrappers.rst

This file was deleted.

153 changes: 100 additions & 53 deletions docs/user/customize_reports.rst
Original file line number Diff line number Diff line change
@@ -1,103 +1,150 @@
.. _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

.. seealso::
Configuring the date format is done at runtime by using the ``--date-format`` option. See :ref:`date format <date-format>` for more information.

.. _config_ini:
.. _property_list_file:

Setup
-----
=====

When you first launch Patcher, a :ref:`setup assistant <setup>` 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 <setup>` 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'``.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Setup</key>
<dict>
<key>first_run_done</key>
<true/>
</dict>
</dict>
</plist>
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 <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 <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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UI</key>
<dict>
<key>HEADER_TEXT</key>
<string>AnyOrg Patch Report</string>
<key>FOOTER_TEXT</key>
<string>AnyOrg Patch Report</string>
<key>FONT_NAME</key>
<string>Assistant</string>
<key>FONT_REGULAR_PATH</key>
<string>/Users/jappleseed/Library/Application Support/Patcher/fonts/Assistant-Regular.ttf</string>
<key>FONT_BOLD_PATH</key>
<string>/Users/jappleseed/Library/Application Support/Patcher/fonts/Assistant-Bold.ttf</string>
</dict>
</dict>
</plist>
The above example would result in a PDF report that looks identical to the :ref:`example PDF image <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 <https://fonts.google.com/specimen/Assistant>`_. 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.

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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Setup</key>
<dict>
<key>first_run_done</key>
<true/>
</dict>
<key>UI</key>
<dict>
<key>HEADER_TEXT</key>
<string>Confidential Report</string>
<key>FOOTER_TEXT</key>
<string>© 2024 Your Company</string>
<key>FONT_NAME</key>
<string>Helvetica</string>
<key>FONT_REGULAR_PATH</key>
<string>/path/to/Helvetica-Regular.ttf</string>
<key>FONT_BOLD_PATH</key>
<string>/path/to/Helvetica-Bold.ttf</string>
</dict>
</dict>
</plist>
65 changes: 6 additions & 59 deletions docs/user/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <base_api_client>` 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.
8 changes: 2 additions & 6 deletions docs/user/prereqs.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
:::
Loading

0 comments on commit 4d43ed2

Please sign in to comment.