PermissionError: [Errno 13] Отказано в доступе при загрузке файла на сайт Django-Pythonanywhere (GNUPG) - PullRequest
0 голосов
/ 10 июня 2019

Я пытаюсь внедрить приложение EDMS майя в мой сайт, управляемый PythonAnywhere, который использует веб-фреймворк Django (1.10).Кроме того, GNUPG установлен и использует файлы GPG для записи ключей, но я не эксперт по этому поводу.

Я успешно загрузил статические файлы, и панель управления EDMS работает;однако, у меня возникают проблемы с загрузкой документов на любой указанный мной setting_gpg_path.Django дает мне ошибку разрешений , которая вращается вокруг моего класса GPG в файле gnupg.py.

Я предполагаю, что эта ошибка связана с природой PythonAnywhere (то есть я намеренноне разрешено выполнять это).Есть ли способ, которым я могу дать себе доступ для доступа к этому файлу?Должен ли я ссылаться на определенное местоположение файла?Соответствующие ошибки / файлы, которые я редактирую:

Traceback

2019-06-10 12:54:27,998: Error executing document upload task; Unable to run gpg - it may not be available., <class 'OSError'>
Traceback (most recent call last):
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/gnupg.py", line 751, in __init__
    p = self._open_subprocess(["--version"])
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/gnupg.py", line 808, in _open_subprocess
    startupinfo=si)
  File "/usr/lib/python3.7/subprocess.py", line 756, in __init__
    restore_signals, start_new_session)
  File "/usr/lib/python3.7/subprocess.py", line 1499, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
PermissionError: [Errno 13] Permission denied: '/home/mywebsite/.virtualenvs/env/bin/gpg1'
**NO MATCH**
During handling of the above exception, another exception occurred:
**NO MATCH**
Traceback (most recent call last):
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/mayan/apps/sources/views.py", line 277, in forms_valid
    user_id=user_id,
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/celery/app/task.py", line 565, in apply_async
    link=link, link_error=link_error, **options)
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/celery/app/task.py", line 763, in apply
    request=request, propagate=throw)
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/celery/app/trace.py", line 355, in eager_trace_task
    uuid, args, kwargs, request)
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/celery/app/trace.py", line 253, in trace_task
    I, R, state, retval = on_error(task_request, exc, uuid)
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/celery/app/trace.py", line 240, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/mayan/apps/sources/tasks.py", line 159, in task_source_handle_upload
    shared_uploaded_file_id=shared_upload.pk, **kwargs
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/celery/app/task.py", line 461, in delay
    return self.apply_async(args, kwargs)
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/celery/app/task.py", line 565, in apply_async
    link=link, link_error=link_error, **options)
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/celery/app/task.py", line 763, in apply
    request=request, propagate=throw)
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/celery/app/trace.py", line 355, in eager_trace_task
    uuid, args, kwargs, request)
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/celery/app/trace.py", line 253, in trace_task
    I, R, state, retval = on_error(task_request, exc, uuid)
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/celery/app/trace.py", line 240, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/mayan/apps/sources/tasks.py", line 193, in task_upload_document
    querystring=querystring, user=user,
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/mayan/apps/sources/models/base.py", line 128, in upload_document
    file_object=file_object, _user=user,
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/mayan/apps/documents/models/document_models.py", line 160, in new_version
    document_version.save(_user=_user)
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/mayan/apps/documents/models/document_version_models.py", line 291, in save
    document_version=self
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/django/db/models/query.py", line 394, in create
    obj.save(force_insert=True, using=self.db)
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/mayan/apps/document_signatures/models.py", line 111, in save
    file_object=file_object
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/mayan/apps/django_gpg/managers.py", line 118, in verify_file
    file_object=file_object, keys=keys
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/mayan/apps/django_gpg/classes.py", line 120, in verify_file
    keys=keys, data_filename=data_filename
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/mayan/apps/django_gpg/classes.py", line 79, in gpg_command
    gnupghome=temporary_directory, gpgbinary=self.kwargs['binary_path']
  File "/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/gnupg.py", line 755, in __init__
    raise OSError(msg)
OSError: Unable to run gpg - it may not be available.

wsgi.py

"""
WSGI config for mayan project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/
"""
import os
import sys

path = '/home/mywebsite/mywebsite'
if path not in sys.path:
    sys.path.append(path)

from django.core.wsgi import get_wsgi_application

os.environ['DJANGO_SETTINGS_MODULE'] = 'mayan.settings.production'

application = get_wsgi_application()

settings.py (не полностью)

from __future__ import unicode_literals

import os
import sys

from django.utils.translation import ugettext_lazy as _

import environ

from mayan.settings.literals import (
    CONFIGURATION_FILENAME, CONFIGURATION_LAST_GOOD_FILENAME,
    DEFAULT_SECRET_KEY, SECRET_KEY_FILENAME, SYSTEM_DIR
)
from mayan.settings.utils import yaml_loads, read_configuration_file

env = environ.Env()

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/

MEDIA_URL = '/home/mywebsite/.virtualenvs/env/lib/python3.7/site-packages/mayan/media/'

MEDIA_ROOT = os.environ.get(
    'MAYAN_MEDIA_ROOT', os.path.join(BASE_DIR, 'media')
)

# SECURITY WARNING: keep the secret key used in production secret!
environment_secret_key = os.environ.get('MAYAN_SECRET_KEY')
if environment_secret_key:
    SECRET_KEY = environment_secret_key
else:
    try:
        with open(os.path.join(MEDIA_ROOT, SYSTEM_DIR, SECRET_KEY_FILENAME)) as file_object:
            SECRET_KEY = file_object.read().strip()
    except IOError:
        SECRET_KEY = DEFAULT_SECRET_KEY

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env.bool('MAYAN_DEBUG', default=False)

ALLOWED_HOSTS = ['www.mywebsite.com']

WSGI_APPLICATION = 'mywebsite.wsgi.application'

# ----------- Celery ----------

CELERY_ACCEPT_CONTENT = ('json',)
CELERY_ALWAYS_EAGER = False
CELERY_CREATE_MISSING_QUEUES = False
CELERY_DISABLE_RATE_LIMITS = True
CELERY_EAGER_PROPAGATES_EXCEPTIONS = True
CELERY_ENABLE_UTC = True
CELERY_QUEUES = []
CELERY_RESULT_SERIALIZER = 'json'
CELERY_ROUTES = {}
CELERY_TASK_SERIALIZER = 'json'
CELERY_TIMEZONE = 'UTC'
CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mywebsite$database',
        'USER': 'mywebsite',
        'PASSWORD': 'xxxxxx',
        'HOST': 'mywebsite.mysql.pythonanywhere-services.com'
    }
}

CONFIGURATION_FILEPATH = os.path.join(MEDIA_ROOT, CONFIGURATION_FILENAME)
CONFIGURATION_LAST_GOOD_FILEPATH = os.path.join(
    MEDIA_ROOT, CONFIGURATION_LAST_GOOD_FILENAME
)

django_gpg / settings.py

from __future__ import unicode_literals

import os

from django.conf import settings
from django.utils.translation import ugettext_lazy as _

from mayan.apps.smart_settings import Namespace

namespace = Namespace(label=_('Signatures'), name='django_gpg')

setting_gpg_home = namespace.add_setting(
    global_name='SIGNATURES_GPG_HOME',
    default=os.path.join(settings.MEDIA_ROOT, 'gpg_home'),
    help_text=_(
        'Home directory used to store keys as well as configuration files.'
    ),
    is_path=True
)
setting_gpg_path = namespace.add_setting(
    global_name='SIGNATURES_GPG_PATH', default='/home/mywebsite/.virtualenvs/env/bin/gpg1', %this is an arbitrary file location
    help_text=_('Path to the GPG binary.'), is_path=True
)
setting_keyserver = namespace.add_setting(
    global_name='SIGNATURES_KEYSERVER', default='pool.sks-keyservers.net',
    help_text=_('Keyserver used to query for keys.')
)

gnupg.py

class GPG(object):

    decode_errors = 'strict'

    result_map = {
        'crypt': Crypt,
        'delete': DeleteResult,
        'generate': GenKey,
        'import': ImportResult,
        'send': SendResult,
        'list': ListKeys,
        'scan': ScanKeys,
        'search': SearchKeys,
        'sign': Sign,
        'verify': Verify,
        'export': ExportResult,
    }

    "Encapsulate access to the gpg executable"
    def __init__(self, gpgbinary='gpg', gnupghome=None, verbose=False,
                 use_agent=False, keyring=None, options=None,
                 secret_keyring=None):
        """Initialize a GPG process wrapper.  Options are:

        gpgbinary -- full pathname for GPG binary.

        gnupghome -- full pathname to where we can find the public and
        private keyrings.  Default is whatever gpg defaults to.
        keyring -- name of alternative keyring file to use, or list of such
        keyrings. If specified, the default keyring is not used.
        options =-- a list of additional options to pass to the GPG binary.
        secret_keyring -- name of alternative secret keyring file to use, or
        list of such keyrings.
        """
        self.gpgbinary = gpgbinary
        self.gnupghome = gnupghome
        if keyring:
            # Allow passing a string or another iterable. Make it uniformly
            # a list of keyring filenames
            if isinstance(keyring, string_types):
                keyring = [keyring]
        self.keyring = keyring
        if secret_keyring:
            # Allow passing a string or another iterable. Make it uniformly
            # a list of keyring filenames
            if isinstance(secret_keyring, string_types):
                secret_keyring = [secret_keyring]
        self.secret_keyring = secret_keyring
        self.verbose = verbose
        self.use_agent = use_agent
        if isinstance(options, str):  # pragma: no cover
            options = [options]
        self.options = options
        # Changed in 0.3.7 to use Latin-1 encoding rather than
        # locale.getpreferredencoding falling back to sys.stdin.encoding
        # falling back to utf-8, because gpg itself uses latin-1 as the default
        # encoding.
        self.encoding = 'latin-1'
        if gnupghome and not os.path.isdir(self.gnupghome):
            os.makedirs(self.gnupghome,0x1C0)
        try:
            p = self._open_subprocess(["--version"])
        except OSError:
            msg = 'Unable to run gpg - it may not be available.'
            logger.exception(msg)
            raise OSError(msg)
        result = self.result_map['verify'](self) # any result will do for this
        self._collect_output(p, result, stdin=p.stdin)
        if p.returncode != 0:  # pragma: no cover
            raise ValueError("Error invoking gpg: %s: %s" % (p.returncode,
                                                             result.stderr))
        m = VERSION_RE.match(result.data)
        if not m:  # pragma: no cover
            self.version = None
        else:
            dot = '.'.encode('ascii')
            self.version = tuple([int(s) for s in m.groups()[0].split(dot)])

    def make_args(self, args, passphrase):
        """
        Make a list of command line elements for GPG. The value of ``args``
        will be appended. The ``passphrase`` argument needs to be True if
        a passphrase will be sent to GPG, else False.
        """
        cmd = [self.gpgbinary, '--status-fd', '2', '--no-tty']
        if self.gnupghome:
            cmd.extend(['--homedir',  no_quote(self.gnupghome)])
        if self.keyring:
            cmd.append('--no-default-keyring')
            for fn in self.keyring:
                cmd.extend(['--keyring', no_quote(fn)])
        if self.secret_keyring:
            for fn in self.secret_keyring:
                cmd.extend(['--secret-keyring', no_quote(fn)])
        if passphrase:
            cmd.extend(['--batch', '--passphrase-fd', '0'])
        if self.use_agent:  # pragma: no cover
            cmd.append('--use-agent')
        if self.options:
            cmd.extend(self.options)
        cmd.extend(args)
        return cmd

    def _open_subprocess(self, args, passphrase=False):
        # Internal method: open a pipe to a GPG subprocess and return
        # the file objects for communicating with it.
        cmd = self.make_args(args, passphrase)
        if self.verbose:  # pragma: no cover
            pcmd = ' '.join(cmd)
            print(pcmd)
        logger.debug("%s", cmd)
        if not STARTUPINFO:
            si = None
        else:  # pragma: no cover
            si = STARTUPINFO()
            si.dwFlags = STARTF_USESHOWWINDOW
            si.wShowWindow = SW_HIDE
        return Popen(cmd, shell=False, stdin=PIPE, stdout=PIPE, stderr=PIPE,
                     startupinfo=si)

1 Ответ

0 голосов
/ 19 июня 2019

Интересно, что я смог загрузить PDF-файлы после перехода с gnupg-python на просто gnupg, но для файлов на базе MS Office требовалась возможность преобразования LibreOffice.

На данный момент я пришел к выводу, чтоподобно gpg или LibreOffice требуется возможность доступа к полностью администрируемому компьютеру / ОС, поэтому онлайн-хосты / консоли, такие как PythonAnywhere, не могут реализовать все функции EDMS майя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...