prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  [BUG] permission error if no consume share is mapped
  ### Description
  
  starting with Paperless-ngx 1.8.0, Paperless on docker does not start when no consume share is mapped:
  
  `
    SystemCheckError: System check identified some issues:
    ERRORS:
    ?: PAPERLESS_CONSUMPTION_DIR is not writeable
  	HINT: Set the permissions of 
    drwxr-xr-x /usr/src/paperless/consume
    to be writeable by the user running the Paperless services
  
  `
  
  I've some containers running without a mapped share, as I don't need a consumption folder. Was no issue in previous versions; I assume the permissions of the folder in the docker container has changed.
  
  ### Steps to reproduce
  
  1. create docker-compose without mapped consumption folder
  2. look at the error message
  
  ### Webserver logs
  
  ```bash
  SystemCheckError: System check identified some issues:
  ERRORS:
  ?: PAPERLESS_CONSUMPTION_DIR is not writeable
  	HINT: Set the permissions of 
  drwxr-xr-x /usr/src/paperless/consume
   to be writeable by the user running the Paperless services
  ```
  
  
  ### Paperless-ngx version
  
  1.8,0
  
  ### Host OS
  
  docker
  
  ### Installation method
  
  Docker - official image
  
  ### Browser
  
  _No response_
  
  ### Configuration changes
  
  _No response_
  
  ### Other
  
  _No response_
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/paperless/checks.py`
  Content:
  ```
  1 import os
  2 import shutil
  3 import stat
  4 
  5 from django.conf import settings
  6 from django.core.checks import Error
  7 from django.core.checks import register
  8 from django.core.checks import Warning
  9 
  10 exists_message = "{} is set but doesn't exist."
  11 exists_hint = "Create a directory at {}"
  12 writeable_message = "{} is not writeable"
  13 writeable_hint = (
  14     "Set the permissions of {} to be writeable by the user running the "
  15     "Paperless services"
  16 )
  17 
  18 
  19 def path_check(var, directory):
  20     messages = []
  21     if directory:
  22         if not os.path.isdir(directory):
  23             messages.append(
  24                 Error(exists_message.format(var), exists_hint.format(directory)),
  25             )
  26         else:
  27             test_file = os.path.join(
  28                 directory,
  29                 f"__paperless_write_test_{os.getpid()}__",
  30             )
  31             try:
  32                 with open(test_file, "w"):
  33                     pass
  34             except PermissionError:
  35                 messages.append(
  36                     Error(
  37                         writeable_message.format(var),
  38                         writeable_hint.format(
  39                             f"\n{stat.filemode(os.stat(directory).st_mode)} "
  40                             f"{directory}\n",
  41                         ),
  42                     ),
  43                 )
  44             finally:
  45                 if os.path.isfile(test_file):
  46                     os.remove(test_file)
  47 
  48     return messages
  49 
  50 
  51 @register()
  52 def paths_check(app_configs, **kwargs):
  53     """
  54     Check the various paths for existence, readability and writeability
  55     """
  56 
  57     return (
  58         path_check("PAPERLESS_DATA_DIR", settings.DATA_DIR)
  59         + path_check("PAPERLESS_TRASH_DIR", settings.TRASH_DIR)
  60         + path_check("PAPERLESS_MEDIA_ROOT", settings.MEDIA_ROOT)
  61         + path_check("PAPERLESS_CONSUMPTION_DIR", settings.CONSUMPTION_DIR)
  62     )
  63 
  64 
  65 @register()
  66 def binaries_check(app_configs, **kwargs):
  67     """
  68     Paperless requires the existence of a few binaries, so we do some checks
  69     for those here.
  70     """
  71 
  72     error = "Paperless can't find {}. Without it, consumption is impossible."
  73     hint = "Either it's not in your ${PATH} or it's not installed."
  74 
  75     binaries = (settings.CONVERT_BINARY, "tesseract")
  76 
  77     check_messages = []
  78     for binary in binaries:
  79         if shutil.which(binary) is None:
  80             check_messages.append(Warning(error.format(binary), hint))
  81 
  82     return check_messages
  83 
  84 
  85 @register()
  86 def debug_mode_check(app_configs, **kwargs):
  87     if settings.DEBUG:
  88         return [
  89             Warning(
  90                 "DEBUG mode is enabled. Disable Debug mode. This is a serious "
  91                 "security issue, since it puts security overides in place which "
  92                 "are meant to be only used during development. This "
  93                 "also means that paperless will tell anyone various "
  94                 "debugging information when something goes wrong.",
  95             ),
  96         ]
  97     else:
  98         return []
  99 
  100 
  101 @register()
  102 def settings_values_check(app_configs, **kwargs):
  103     """
  104     Validates at least some of the user provided settings
  105     """
  106 
  107     def _ocrmypdf_settings_check():
  108         """
  109         Validates some of the arguments which will be provided to ocrmypdf
  110         against the valid options.  Use "ocrmypdf --help" to see the valid
  111         inputs
  112         """
  113         msgs = []
  114         if settings.OCR_OUTPUT_TYPE not in {
  115             "pdfa",
  116             "pdf",
  117             "pdfa-1",
  118             "pdfa-2",
  119             "pdfa-3",
  120         }:
  121             msgs.append(
  122                 Error(f'OCR output type "{settings.OCR_OUTPUT_TYPE}" is not valid'),
  123             )
  124 
  125         if settings.OCR_MODE not in {"force", "skip", "redo_ocr"}:
  126             msgs.append(Error(f'OCR output mode "{settings.OCR_MODE}" is not valid'))
  127 
  128         if settings.OCR_CLEAN not in {"clean", "clean_final"}:
  129             msgs.append(Error(f'OCR clean mode "{settings.OCR_CLEAN}" is not valid'))
  130         return msgs
  131 
  132     def _timezone_validate():
  133         """
  134         Validates the user provided timezone is a valid timezone
  135         """
  136         try:
  137             import zoneinfo
  138         except ImportError:  # pragma: nocover
  139             import backports.zoneinfo as zoneinfo
  140         msgs = []
  141         if settings.TIME_ZONE not in zoneinfo.available_timezones():
  142             msgs.append(
  143                 Error(f'Timezone "{settings.TIME_ZONE}" is not a valid timezone'),
  144             )
  145         return msgs
  146 
  147     return _ocrmypdf_settings_check() + _timezone_validate()
  148
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/src/paperless/checks.py b/src/paperless/checks.py
  --- a/src/paperless/checks.py
  +++ b/src/paperless/checks.py
  @@ -1,4 +1,6 @@
  +import grp
   import os
  +import pwd
   import shutil
   import stat
   
  @@ -32,12 +34,15 @@
                   with open(test_file, "w"):
                       pass
               except PermissionError:
  +                dir_stat = os.stat(directory)
  +                dir_mode = stat.filemode(dir_stat.st_mode)
  +                dir_owner = pwd.getpwuid(dir_stat.st_uid).pw_name
  +                dir_group = grp.getgrgid(dir_stat.st_gid).gr_name
                   messages.append(
                       Error(
                           writeable_message.format(var),
                           writeable_hint.format(
  -                            f"\n{stat.filemode(os.stat(directory).st_mode)} "
  -                            f"{directory}\n",
  +                            f"\n{dir_mode} {dir_owner} {dir_group} " f"{directory}\n",
                           ),
                       ),
                   )
  
verification_info: {"golden_diff": "diff --git a/src/paperless/checks.py b/src/paperless/checks.py\n--- a/src/paperless/checks.py\n+++ b/src/paperless/checks.py\n@@ -1,4 +1,6 @@\n+import grp\n import os\n+import pwd\n import shutil\n import stat\n \n@@ -32,12 +34,15 @@\n                 with open(test_file, \"w\"):\n                     pass\n             except PermissionError:\n+                dir_stat = os.stat(directory)\n+                dir_mode = stat.filemode(dir_stat.st_mode)\n+                dir_owner = pwd.getpwuid(dir_stat.st_uid).pw_name\n+                dir_group = grp.getgrgid(dir_stat.st_gid).gr_name\n                 messages.append(\n                     Error(\n                         writeable_message.format(var),\n                         writeable_hint.format(\n-                            f\"\\n{stat.filemode(os.stat(directory).st_mode)} \"\n-                            f\"{directory}\\n\",\n+                            f\"\\n{dir_mode} {dir_owner} {dir_group} \" f\"{directory}\\n\",\n                         ),\n                     ),\n                 )\n", "issue": "[BUG] permission error if no consume share is mapped\n### Description\r\n\r\nstarting with Paperless-ngx 1.8.0, Paperless on docker does not start when no consume share is mapped:\r\n\r\n`\r\n  SystemCheckError: System check identified some issues:\r\n  ERRORS:\r\n  ?: PAPERLESS_CONSUMPTION_DIR is not writeable\r\n\tHINT: Set the permissions of \r\n  drwxr-xr-x /usr/src/paperless/consume\r\n  to be writeable by the user running the Paperless services\r\n\r\n`\r\n\r\nI've some containers running without a mapped share, as I don't need a consumption folder. Was no issue in previous versions; I assume the permissions of the folder in the docker container has changed.\r\n\r\n### Steps to reproduce\r\n\r\n1. create docker-compose without mapped consumption folder\r\n2. look at the error message\r\n\r\n### Webserver logs\r\n\r\n```bash\r\nSystemCheckError: System check identified some issues:\r\nERRORS:\r\n?: PAPERLESS_CONSUMPTION_DIR is not writeable\r\n\tHINT: Set the permissions of \r\ndrwxr-xr-x /usr/src/paperless/consume\r\n to be writeable by the user running the Paperless services\r\n```\r\n\r\n\r\n### Paperless-ngx version\r\n\r\n1.8,0\r\n\r\n### Host OS\r\n\r\ndocker\r\n\r\n### Installation method\r\n\r\nDocker - official image\r\n\r\n### Browser\r\n\r\n_No response_\r\n\r\n### Configuration changes\r\n\r\n_No response_\r\n\r\n### Other\r\n\r\n_No response_\n", "before_files": [{"content": "import os\nimport shutil\nimport stat\n\nfrom django.conf import settings\nfrom django.core.checks import Error\nfrom django.core.checks import register\nfrom django.core.checks import Warning\n\nexists_message = \"{} is set but doesn't exist.\"\nexists_hint = \"Create a directory at {}\"\nwriteable_message = \"{} is not writeable\"\nwriteable_hint = (\n    \"Set the permissions of {} to be writeable by the user running the \"\n    \"Paperless services\"\n)\n\n\ndef path_check(var, directory):\n    messages = []\n    if directory:\n        if not os.path.isdir(directory):\n            messages.append(\n                Error(exists_message.format(var), exists_hint.format(directory)),\n            )\n        else:\n            test_file = os.path.join(\n                directory,\n                f\"__paperless_write_test_{os.getpid()}__\",\n            )\n            try:\n                with open(test_file, \"w\"):\n                    pass\n            except PermissionError:\n                messages.append(\n                    Error(\n                        writeable_message.format(var),\n                        writeable_hint.format(\n                            f\"\\n{stat.filemode(os.stat(directory).st_mode)} \"\n                            f\"{directory}\\n\",\n                        ),\n                    ),\n                )\n            finally:\n                if os.path.isfile(test_file):\n                    os.remove(test_file)\n\n    return messages\n\n\n@register()\ndef paths_check(app_configs, **kwargs):\n    \"\"\"\n    Check the various paths for existence, readability and writeability\n    \"\"\"\n\n    return (\n        path_check(\"PAPERLESS_DATA_DIR\", settings.DATA_DIR)\n        + path_check(\"PAPERLESS_TRASH_DIR\", settings.TRASH_DIR)\n        + path_check(\"PAPERLESS_MEDIA_ROOT\", settings.MEDIA_ROOT)\n        + path_check(\"PAPERLESS_CONSUMPTION_DIR\", settings.CONSUMPTION_DIR)\n    )\n\n\n@register()\ndef binaries_check(app_configs, **kwargs):\n    \"\"\"\n    Paperless requires the existence of a few binaries, so we do some checks\n    for those here.\n    \"\"\"\n\n    error = \"Paperless can't find {}. Without it, consumption is impossible.\"\n    hint = \"Either it's not in your ${PATH} or it's not installed.\"\n\n    binaries = (settings.CONVERT_BINARY, \"tesseract\")\n\n    check_messages = []\n    for binary in binaries:\n        if shutil.which(binary) is None:\n            check_messages.append(Warning(error.format(binary), hint))\n\n    return check_messages\n\n\n@register()\ndef debug_mode_check(app_configs, **kwargs):\n    if settings.DEBUG:\n        return [\n            Warning(\n                \"DEBUG mode is enabled. Disable Debug mode. This is a serious \"\n                \"security issue, since it puts security overides in place which \"\n                \"are meant to be only used during development. This \"\n                \"also means that paperless will tell anyone various \"\n                \"debugging information when something goes wrong.\",\n            ),\n        ]\n    else:\n        return []\n\n\n@register()\ndef settings_values_check(app_configs, **kwargs):\n    \"\"\"\n    Validates at least some of the user provided settings\n    \"\"\"\n\n    def _ocrmypdf_settings_check():\n        \"\"\"\n        Validates some of the arguments which will be provided to ocrmypdf\n        against the valid options.  Use \"ocrmypdf --help\" to see the valid\n        inputs\n        \"\"\"\n        msgs = []\n        if settings.OCR_OUTPUT_TYPE not in {\n            \"pdfa\",\n            \"pdf\",\n            \"pdfa-1\",\n            \"pdfa-2\",\n            \"pdfa-3\",\n        }:\n            msgs.append(\n                Error(f'OCR output type \"{settings.OCR_OUTPUT_TYPE}\" is not valid'),\n            )\n\n        if settings.OCR_MODE not in {\"force\", \"skip\", \"redo_ocr\"}:\n            msgs.append(Error(f'OCR output mode \"{settings.OCR_MODE}\" is not valid'))\n\n        if settings.OCR_CLEAN not in {\"clean\", \"clean_final\"}:\n            msgs.append(Error(f'OCR clean mode \"{settings.OCR_CLEAN}\" is not valid'))\n        return msgs\n\n    def _timezone_validate():\n        \"\"\"\n        Validates the user provided timezone is a valid timezone\n        \"\"\"\n        try:\n            import zoneinfo\n        except ImportError:  # pragma: nocover\n            import backports.zoneinfo as zoneinfo\n        msgs = []\n        if settings.TIME_ZONE not in zoneinfo.available_timezones():\n            msgs.append(\n                Error(f'Timezone \"{settings.TIME_ZONE}\" is not a valid timezone'),\n            )\n        return msgs\n\n    return _ocrmypdf_settings_check() + _timezone_validate()\n", "path": "src/paperless/checks.py"}], "after_files": [{"content": "import grp\nimport os\nimport pwd\nimport shutil\nimport stat\n\nfrom django.conf import settings\nfrom django.core.checks import Error\nfrom django.core.checks import register\nfrom django.core.checks import Warning\n\nexists_message = \"{} is set but doesn't exist.\"\nexists_hint = \"Create a directory at {}\"\nwriteable_message = \"{} is not writeable\"\nwriteable_hint = (\n    \"Set the permissions of {} to be writeable by the user running the \"\n    \"Paperless services\"\n)\n\n\ndef path_check(var, directory):\n    messages = []\n    if directory:\n        if not os.path.isdir(directory):\n            messages.append(\n                Error(exists_message.format(var), exists_hint.format(directory)),\n            )\n        else:\n            test_file = os.path.join(\n                directory,\n                f\"__paperless_write_test_{os.getpid()}__\",\n            )\n            try:\n                with open(test_file, \"w\"):\n                    pass\n            except PermissionError:\n                dir_stat = os.stat(directory)\n                dir_mode = stat.filemode(dir_stat.st_mode)\n                dir_owner = pwd.getpwuid(dir_stat.st_uid).pw_name\n                dir_group = grp.getgrgid(dir_stat.st_gid).gr_name\n                messages.append(\n                    Error(\n                        writeable_message.format(var),\n                        writeable_hint.format(\n                            f\"\\n{dir_mode} {dir_owner} {dir_group} \" f\"{directory}\\n\",\n                        ),\n                    ),\n                )\n            finally:\n                if os.path.isfile(test_file):\n                    os.remove(test_file)\n\n    return messages\n\n\n@register()\ndef paths_check(app_configs, **kwargs):\n    \"\"\"\n    Check the various paths for existence, readability and writeability\n    \"\"\"\n\n    return (\n        path_check(\"PAPERLESS_DATA_DIR\", settings.DATA_DIR)\n        + path_check(\"PAPERLESS_TRASH_DIR\", settings.TRASH_DIR)\n        + path_check(\"PAPERLESS_MEDIA_ROOT\", settings.MEDIA_ROOT)\n        + path_check(\"PAPERLESS_CONSUMPTION_DIR\", settings.CONSUMPTION_DIR)\n    )\n\n\n@register()\ndef binaries_check(app_configs, **kwargs):\n    \"\"\"\n    Paperless requires the existence of a few binaries, so we do some checks\n    for those here.\n    \"\"\"\n\n    error = \"Paperless can't find {}. Without it, consumption is impossible.\"\n    hint = \"Either it's not in your ${PATH} or it's not installed.\"\n\n    binaries = (settings.CONVERT_BINARY, \"tesseract\")\n\n    check_messages = []\n    for binary in binaries:\n        if shutil.which(binary) is None:\n            check_messages.append(Warning(error.format(binary), hint))\n\n    return check_messages\n\n\n@register()\ndef debug_mode_check(app_configs, **kwargs):\n    if settings.DEBUG:\n        return [\n            Warning(\n                \"DEBUG mode is enabled. Disable Debug mode. This is a serious \"\n                \"security issue, since it puts security overides in place which \"\n                \"are meant to be only used during development. This \"\n                \"also means that paperless will tell anyone various \"\n                \"debugging information when something goes wrong.\",\n            ),\n        ]\n    else:\n        return []\n\n\n@register()\ndef settings_values_check(app_configs, **kwargs):\n    \"\"\"\n    Validates at least some of the user provided settings\n    \"\"\"\n\n    def _ocrmypdf_settings_check():\n        \"\"\"\n        Validates some of the arguments which will be provided to ocrmypdf\n        against the valid options.  Use \"ocrmypdf --help\" to see the valid\n        inputs\n        \"\"\"\n        msgs = []\n        if settings.OCR_OUTPUT_TYPE not in {\n            \"pdfa\",\n            \"pdf\",\n            \"pdfa-1\",\n            \"pdfa-2\",\n            \"pdfa-3\",\n        }:\n            msgs.append(\n                Error(f'OCR output type \"{settings.OCR_OUTPUT_TYPE}\" is not valid'),\n            )\n\n        if settings.OCR_MODE not in {\"force\", \"skip\", \"redo_ocr\"}:\n            msgs.append(Error(f'OCR output mode \"{settings.OCR_MODE}\" is not valid'))\n\n        if settings.OCR_CLEAN not in {\"clean\", \"clean_final\"}:\n            msgs.append(Error(f'OCR clean mode \"{settings.OCR_CLEAN}\" is not valid'))\n        return msgs\n\n    def _timezone_validate():\n        \"\"\"\n        Validates the user provided timezone is a valid timezone\n        \"\"\"\n        try:\n            import zoneinfo\n        except ImportError:  # pragma: nocover\n            import backports.zoneinfo as zoneinfo\n        msgs = []\n        if settings.TIME_ZONE not in zoneinfo.available_timezones():\n            msgs.append(\n                Error(f'Timezone \"{settings.TIME_ZONE}\" is not a valid timezone'),\n            )\n        return msgs\n\n    return _ocrmypdf_settings_check() + _timezone_validate()\n", "path": "src/paperless/checks.py"}]}