Hyperkitty not receaving messages / empty archive [Django] ERROR (EXTERNAL IP): Internal Server Error: /hyperkitty/api/mailman/urls
Hello Everybody,
i have set up a fresh mailman3 installation with maxkings Docker compose image (https://github.com/maxking/docker-mailman) I've got it working except i get a very strange hyperkitty error:
Each time i'm sending a post to the list, it gets distributed to the emailadresses of the list, and at the same time i'm geting a bunch of error Mails. And: There are no Mails visible in the Archive. The directory under core/var/archive/hyperkitty/spool/ listst the mails....though... Hyperkitty-Api-Key in the docker-compose.yml is set via .env Variabel, so it should be identical.
That ist the error Mail i receive:
Can annybody hint me where to search further, what is wrong? If searched insesivly but found nothing as of jet.... :-(
Thank you in advance! Helge
Internal Server Error: /hyperkitty/api/mailman/urls
TypeError at /hyperkitty/api/mailman/urls unsupported operand types(s) or combination of types: 'str' and 'NoneType'
Request Method: GET Request URL:http://mailman-web:8000/hyperkitty/api/mailman/urls?mlist=test%40lists.mydomain.net&msgid=2291673b-c760-4651-8025-ae170429d587%40web.de Django Version: 4.1.12 Python Executable: /usr/bin/uwsgi Python Version: 3.11.6 Python Path: ['.', '', '/usr/lib/python311.zip', '/usr/lib/python3.11', '/usr/lib/python3.11/lib-dynload', '/usr/lib/python3.11/site-packages'] Server time: Tue, 21 Jan 2025 13:12:13 +0000 Installed Applications: ['hyperkitty', 'postorius', 'django_mailman3', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'django_gravatar', 'compressor', 'haystack', 'django_extensions', 'django_q', 'allauth', 'allauth.account', 'allauth.socialaccount', 'django_mailman3.lib.auth.fedora', 'allauth.socialaccount.providers.openid', 'allauth.socialaccount.providers.github', 'allauth.socialaccount.providers.gitlab', 'allauth.socialaccount.providers.google'] Installed Middleware: ('django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', 'allauth.account.middleware.AccountMiddleware', 'django_mailman3.middleware.TimezoneMiddleware', 'postorius.middleware.PostoriusMiddleware')
Traceback (most recent call last): File "/usr/lib/python3.11/site-packages/django/core/handlers/exception.py", line 56, in inner response = get_response(request) File "/usr/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/usr/lib/python3.11/site-packages/hyperkitty/views/mailman.py", line 109, in _decorator not hmac.compare_digest(
Exception Type: TypeError at /hyperkitty/api/mailman/urls Exception Value: unsupported operand types(s) or combination of types: 'str' and 'NoneType' Raised during: hyperkitty.views.mailman.urls Request information: USER: AnonymousUser
GET: mlist = 'test@lists.mydomain.net' msgid = '2291673b-c760-4651-8025-ae170429d587@web.de'
POST: No POST data
FILES: No FILES data
COOKIES: No cookie data
META: HTTP_ACCEPT = '*/*' HTTP_ACCEPT_ENCODING = 'gzip, deflate' HTTP_AUTHORIZATION = 'Token 3ezHkyhUqlD0qB2LiLb4xORyuVFCwimlVZidlOk7XJqjy9QBaNM6O0w4aSR162bN2tIFMdWFKOpfQ1Zq5QYrrVE4IsNFGvkLfGwbf58uENJmUD2yvA0pGXTlvLc3KFD1' HTTP_CONNECTION = 'keep-alive' HTTP_HOST = 'mailman-web:8000' HTTP_USER_AGENT = 'python-requests/2.31.0' PATH_INFO = '/hyperkitty/api/mailman/urls' QUERY_STRING = 'mlist=test%40lists.mydomain.net&msgid=2291673b-c760-4651-8025-ae170429d587%40web.de' REMOTE_ADDR = '172.26.0.2' REQUEST_METHOD = 'GET' REQUEST_URI = '/hyperkitty/api/mailman/urls?mlist=test%40lists.mydomain.net&msgid=2291673b-c760-4651-8025-ae170429d587%40web.de' SCRIPT_NAME = '' SERVER_NAME = 'mailman-web' SERVER_PORT = '8000' SERVER_PROTOCOL = 'HTTP/1.1' uwsgi.core = 1 uwsgi.node = b'mailman-web' uwsgi.version = b'2.0.22' wsgi.errors = <_io.TextIOWrapper name=2 mode='w' encoding='UTF-8'> wsgi.file_wrapper = <built-in function uwsgi_sendfile> wsgi.input = <uwsgi._Input object at 0x790fb0ef82b0> wsgi.multiprocess = True wsgi.multithread = True wsgi.run_once = False wsgi.url_scheme = 'http' wsgi.version = '(1, 0)'
Settings: Using settings module settings ABSOLUTE_URL_OVERRIDES = {} ACCOUNT_AUTHENTICATION_METHOD = 'username_email' ACCOUNT_DEFAULT_HTTP_PROTOCOL = 'https' ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_EMAIL_VERIFICATION = 'mandatory' ACCOUNT_UNIQUE_EMAIL = True ADMINS = "(('Mailman Suite Admin', 'it@mydomain.net'),)" ALLOWED_HOSTS = ['localhost', 'mailman-web', '172.26.0.3', 'lists.mydomain.net', 'lists.mydomain.net'] APPEND_SLASH = True AUTHENTICATION_BACKENDS = "('django.contrib.auth.backends.ModelBackend', 'allauth.account.auth_backends.AuthenticationBackend')" AUTH_PASSWORD_VALIDATORS = '********************' AUTH_USER_MODEL = 'auth.User' BASE_DIR = '/opt/mailman-web' CACHES = {'default': {'BACKEND': 'diskcache.DjangoCache', 'LOCATION': '/opt/mailman-web-data/diskcache', 'OPTIONS': {'size_limit': 1073741824}}} CACHE_MIDDLEWARE_ALIAS = 'default' CACHE_MIDDLEWARE_KEY_PREFIX = '********************' CACHE_MIDDLEWARE_SECONDS = 600 COMPRESSORS = {'css': 'compressor.css.CssCompressor', 'js': 'compressor.js.JsCompressor'} COMPRESS_CACHEABLE_PRECOMPILERS = '()' COMPRESS_CACHE_BACKEND = 'default' COMPRESS_CACHE_KEY_FUNCTION = '********************' COMPRESS_CLEAN_CSS_ARGUMENTS = '' COMPRESS_CLEAN_CSS_BINARY = 'cleancss' COMPRESS_CLOSURE_COMPILER_ARGUMENTS = '' COMPRESS_CLOSURE_COMPILER_BINARY = 'java -jar compiler.jar' COMPRESS_CSS_HASHING_METHOD = 'mtime' COMPRESS_DATA_URI_MAX_SIZE = 1024 COMPRESS_DEBUG_TOGGLE = None COMPRESS_ENABLED = True COMPRESS_FILTERS = {'css': ['compressor.filters.css_default.CssAbsoluteFilter', 'compressor.filters.cssmin.rCSSMinFilter'], 'js': ['compressor.filters.jsmin.rJSMinFilter']} COMPRESS_JINJA2_GET_ENVIRONMENT = <function CompressorConf.JINJA2_GET_ENVIRONMENT at 0x790fb2323420> COMPRESS_MINT_DELAY = 30 COMPRESS_MTIME_DELAY = 10 COMPRESS_OFFLINE = False COMPRESS_OFFLINE_CONTEXT = {'STATIC_URL': '/static/'} COMPRESS_OFFLINE_MANIFEST = 'manifest.json' COMPRESS_OFFLINE_MANIFEST_STORAGE = 'compressor.storage.OfflineManifestFileStorage' COMPRESS_OFFLINE_TIMEOUT = 31536000 COMPRESS_OUTPUT_DIR = 'CACHE' COMPRESS_PARSER = 'compressor.parser.AutoSelectParser' COMPRESS_PRECOMPILERS = "(('text/less', 'lessc {infile} {outfile}'), ('text/x-scss', 'sassc -t compressed {infile} {outfile}'), ('text/x-sass', 'sassc -t compressed {infile} {outfile}'))" COMPRESS_REBUILD_TIMEOUT = 2592000 COMPRESS_ROOT = '/opt/mailman-web-data/static' COMPRESS_STORAGE = 'compressor.storage.CompressorFileStorage' COMPRESS_TEMPLATE_FILTER_CONTEXT = {'STATIC_URL': '/static/'} COMPRESS_URL = '/static/' COMPRESS_URL_PLACEHOLDER = '/__compressor_url_placeholder__/' COMPRESS_VERBOSE = False COMPRESS_YUGLIFY_BINARY = 'yuglify' COMPRESS_YUGLIFY_CSS_ARGUMENTS = '--terminal' COMPRESS_YUGLIFY_JS_ARGUMENTS = '--terminal' COMPRESS_YUI_BINARY = 'java -jar yuicompressor.jar' COMPRESS_YUI_CSS_ARGUMENTS = '' COMPRESS_YUI_JS_ARGUMENTS = '' CSRF_COOKIE_AGE = 31449600 CSRF_COOKIE_DOMAIN = None CSRF_COOKIE_HTTPONLY = False CSRF_COOKIE_MASKED = False CSRF_COOKIE_NAME = 'csrftoken' CSRF_COOKIE_PATH = '/' CSRF_COOKIE_SAMESITE = 'Lax' CSRF_COOKIE_SECURE = False CSRF_FAILURE_VIEW = 'django.views.csrf.csrf_failure' CSRF_HEADER_NAME = 'HTTP_X_CSRFTOKEN' CSRF_TRUSTED_ORIGINS = [] CSRF_USE_SESSIONS = False DATABASES = {'default': {'NAME': 'mailmandb', 'USER': 'mailman', 'PASSWORD': '********************', 'HOST': 'database', 'PORT': '', 'CONN_MAX_AGE': 600, 'CONN_HEALTH_CHECKS': False, 'ENGINE': 'django.db.backends.postgresql', 'ATOMIC_REQUESTS': False, 'AUTOCOMMIT': True, 'OPTIONS': {}, 'TIME_ZONE': None, 'TEST': {'CHARSET': None, 'COLLATION': None, 'MIGRATE': True, 'MIRROR': None, 'NAME': None}}} DATABASE_ROUTERS = [] DATA_UPLOAD_MAX_MEMORY_SIZE = 2621440 DATA_UPLOAD_MAX_NUMBER_FIELDS = 1000 DATA_UPLOAD_MAX_NUMBER_FILES = 100 DATETIME_FORMAT = 'N j, Y, P' DATETIME_INPUT_FORMATS = ['%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M:%S.%f', '%Y-%m-%d %H:%M', '%m/%d/%Y %H:%M:%S', '%m/%d/%Y %H:%M:%S.%f', '%m/%d/%Y %H:%M', '%m/%d/%y %H:%M:%S', '%m/%d/%y %H:%M:%S.%f', '%m/%d/%y %H:%M'] DATE_FORMAT = 'N j, Y' DATE_INPUT_FORMATS = ['%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', '%b %d %Y', '%b %d, %Y', '%d %b %Y', '%d %b, %Y', '%B %d %Y', '%B %d, %Y', '%d %B %Y', '%d %B, %Y'] DEBUG = False DEBUG_PROPAGATE_EXCEPTIONS = False DECIMAL_SEPARATOR = '.' DEFAULT_APPS = ['hyperkitty', 'postorius', 'django_mailman3', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'django_gravatar', 'compressor', 'haystack', 'django_extensions', 'django_q', 'allauth', 'allauth.account', 'allauth.socialaccount'] DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' DEFAULT_CHARSET = 'utf-8' DEFAULT_EXCEPTION_REPORTER = 'django.views.debug.ExceptionReporter' DEFAULT_EXCEPTION_REPORTER_FILTER = 'django.views.debug.SafeExceptionReporterFilter' DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage' DEFAULT_FROM_EMAIL = 'lists@mydomain.net' DEFAULT_INDEX_TABLESPACE = '' DEFAULT_TABLESPACE = '' DISALLOWED_USER_AGENTS = [] DISKCACHE_PATH = '/opt/mailman-web-data/diskcache' DISKCACHE_SIZE = 1073741824 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = '172.26.0.5' EMAIL_HOST_PASSWORD = '********************' EMAIL_HOST_USER = '' EMAIL_PORT = 25 EMAIL_SSL_CERTFILE = None EMAIL_SSL_KEYFILE = '********************' EMAIL_SUBJECT_PREFIX = '[Django] ' EMAIL_TIMEOUT = None EMAIL_USE_LOCALTIME = False EMAIL_USE_SSL = False EMAIL_USE_TLS = False FILE_UPLOAD_DIRECTORY_PERMISSIONS = None FILE_UPLOAD_HANDLERS = ['django.core.files.uploadhandler.MemoryFileUploadHandler', 'django.core.files.uploadhandler.TemporaryFileUploadHandler'] FILE_UPLOAD_MAX_MEMORY_SIZE = 2621440 FILE_UPLOAD_PERMISSIONS = 420 FILE_UPLOAD_TEMP_DIR = None FILTER_VHOST = False FIRST_DAY_OF_WEEK = 0 FIXTURE_DIRS = [] FORCE_SCRIPT_NAME = None FORMAT_MODULE_PATH = None FORM_RENDERER = 'django.forms.renderers.DjangoTemplates' HAYSTACK_CONNECTIONS = {'default': {'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine', 'PATH': '/opt/mailman-web-data/fulltext_index'}} IGNORABLE_404_URLS = [] INSTALLED_APPS = ['hyperkitty', 'postorius', 'django_mailman3', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'django_gravatar', 'compressor', 'haystack', 'django_extensions', 'django_q', 'allauth', 'allauth.account', 'allauth.socialaccount', 'django_mailman3.lib.auth.fedora', 'allauth.socialaccount.providers.openid', 'allauth.socialaccount.providers.github', 'allauth.socialaccount.providers.gitlab', 'allauth.socialaccount.providers.google'] INTERNAL_IPS = [] LANGUAGES = [('af', 'Afrikaans'), ('ar', 'Arabic'), ('ar-dz', 'Algerian Arabic'), ('ast', 'Asturian'), ('az', 'Azerbaijani'), ('bg', 'Bulgarian'), ('be', 'Belarusian'), ('bn', 'Bengali'), ('br', 'Breton'), ('bs', 'Bosnian'), ('ca', 'Catalan'), ('cs', 'Czech'), ('cy', 'Welsh'), ('da', 'Danish'), ('de', 'German'), ('dsb', 'Lower Sorbian'), ('el', 'Greek'), ('en', 'English'), ('en-au', 'Australian English'), ('en-gb', 'British English'), ('eo', 'Esperanto'), ('es', 'Spanish'), ('es-ar', 'Argentinian Spanish'), ('es-co', 'Colombian Spanish'), ('es-mx', 'Mexican Spanish'), ('es-ni', 'Nicaraguan Spanish'), ('es-ve', 'Venezuelan Spanish'), ('et', 'Estonian'), ('eu', 'Basque'), ('fa', 'Persian'), ('fi', 'Finnish'), ('fr', 'French'), ('fy', 'Frisian'), ('ga', 'Irish'), ('gd', 'Scottish Gaelic'), ('gl', 'Galician'), ('he', 'Hebrew'), ('hi', 'Hindi'), ('hr', 'Croatian'), ('hsb', 'Upper Sorbian'), ('hu', 'Hungarian'), ('hy', 'Armenian'), ('ia', 'Interlingua'), ('id', 'Indonesian'), ('ig', 'Igbo'), ('io', 'Ido'), ('is', 'Icelandic'), ('it', 'Italian'), ('ja', 'Japanese'), ('ka', 'Georgian'), ('kab', 'Kabyle'), ('kk', 'Kazakh'), ('km', 'Khmer'), ('kn', 'Kannada'), ('ko', 'Korean'), ('ky', 'Kyrgyz'), ('lb', 'Luxembourgish'), ('lt', 'Lithuanian'), ('lv', 'Latvian'), ('mk', 'Macedonian'), ('ml', 'Malayalam'), ('mn', 'Mongolian'), ('mr', 'Marathi'), ('ms', 'Malay'), ('my', 'Burmese'), ('nb', 'Norwegian Bokmål'), ('ne', 'Nepali'), ('nl', 'Dutch'), ('nn', 'Norwegian Nynorsk'), ('os', 'Ossetic'), ('pa', 'Punjabi'), ('pl', 'Polish'), ('pt', 'Portuguese'), ('pt-br', 'Brazilian Portuguese'), ('ro', 'Romanian'), ('ru', 'Russian'), ('sk', 'Slovak'), ('sl', 'Slovenian'), ('sq', 'Albanian'), ('sr', 'Serbian'), ('sr-latn', 'Serbian Latin'), ('sv', 'Swedish'), ('sw', 'Swahili'), ('ta', 'Tamil'), ('te', 'Telugu'), ('tg', 'Tajik'), ('th', 'Thai'), ('tk', 'Turkmen'), ('tr', 'Turkish'), ('tt', 'Tatar'), ('udm', 'Udmurt'), ('uk', 'Ukrainian'), ('ur', 'Urdu'), ('uz', 'Uzbek'), ('vi', 'Vietnamese'), ('zh-hans', 'Simplified Chinese'), ('zh-hant', 'Traditional Chinese')] LANGUAGES_BIDI = ['he', 'ar', 'ar-dz', 'fa', 'ur'] LANGUAGE_CODE = 'en-us' LANGUAGE_COOKIE_AGE = None LANGUAGE_COOKIE_DOMAIN = None LANGUAGE_COOKIE_HTTPONLY = False LANGUAGE_COOKIE_NAME = 'django_language' LANGUAGE_COOKIE_PATH = '/' LANGUAGE_COOKIE_SAMESITE = None LANGUAGE_COOKIE_SECURE = False LOCALE_PATHS = [] LOGGING = {'version': 1, 'disable_existing_loggers': False, 'filters': {'require_debug_false': {'()': 'django.utils.log.RequireDebugFalse'}}, 'handlers': {'mail_admins': {'level': 'ERROR', 'filters': ['require_debug_false'], 'class': 'django.utils.log.AdminEmailHandler'}, 'file': {'level': 'INFO', 'class': 'logging.handlers.RotatingFileHandler', 'filename': '/opt/mailman-web-data/logs/mailmanweb.log', 'formatter': 'verbose'}, 'console': {'class': 'logging.StreamHandler', 'formatter': 'simple', 'level': 'INFO', 'stream': <_io.TextIOWrapper name=2 mode='w' encoding='UTF-8'>}}, 'loggers': {'django.request': {'handlers': ['mail_admins', 'file'], 'level': 'INFO', 'propagate': True}, 'django': {'handlers': ['file'], 'level': 'INFO', 'propagate': True}, 'hyperkitty': {'handlers': ['file'], 'level': 'INFO', 'propagate': True}, 'postorius': {'handlers': ['file'], 'level': 'INFO', 'propagate': True}}, 'formatters': {'verbose': {'format': '%(levelname)s %(asctime)s %(process)d %(name)s %(message)s'}, 'simple': {'format': '%(levelname)s %(message)s'}}} LOGGING_CONFIG = 'logging.config.dictConfig' LOGIN_REDIRECT_URL = 'list_index' LOGIN_URL = 'account_login' LOGOUT_REDIRECT_URL = None LOGOUT_URL = 'account_logout' MAILMAN_ARCHIVER_FROM = "('172.26.0.2',)" MAILMAN_ARCHIVER_KEY = '********************' MAILMAN_REST_API_PASS = '********************' MAILMAN_REST_API_URL = '********************' MAILMAN_REST_API_USER = '********************' MAILMAN_WEB_SOCIAL_AUTH = ['django_mailman3.lib.auth.fedora', 'allauth.socialaccount.providers.openid', 'allauth.socialaccount.providers.github', 'allauth.socialaccount.providers.gitlab', 'allauth.socialaccount.providers.google'] MANAGERS = [] MEDIA_ROOT = '' MEDIA_URL = '/' MESSAGE_STORAGE = 'django.contrib.messages.storage.fallback.FallbackStorage' MESSAGE_TAGS = {40: 'danger'} MIDDLEWARE = "('django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', 'allauth.account.middleware.AccountMiddleware', 'django_mailman3.middleware.TimezoneMiddleware', 'postorius.middleware.PostoriusMiddleware')" MIGRATION_MODULES = {} MONTH_DAY_FORMAT = 'F j' NUMBER_GROUPING = 0 PASSWORD_HASHERS = '********************' PASSWORD_RESET_TIMEOUT = '********************' POSTORIUS_TEMPLATE_BASE_URL = 'http://mailman-web:8000' PREPEND_WWW = False Q_CLUSTER = {'timeout': 300, 'retry': 300, 'save_limit': 100, 'orm': 'default'} ROOT_URLCONF = 'urls' SECRET_KEY = '********************' SECRET_KEY_FALLBACKS = '********************' SECURE_CONTENT_TYPE_NOSNIFF = True SECURE_CROSS_ORIGIN_OPENER_POLICY = 'same-origin' SECURE_HSTS_INCLUDE_SUBDOMAINS = False SECURE_HSTS_PRELOAD = False SECURE_HSTS_SECONDS = 0 SECURE_PROXY_SSL_HEADER = None SECURE_REDIRECT_EXEMPT = [] SECURE_REFERRER_POLICY = 'same-origin' SECURE_SSL_HOST = None SECURE_SSL_REDIRECT = False SERVER_EMAIL = 'lists@mydomain.net' SESSION_CACHE_ALIAS = 'default' SESSION_COOKIE_AGE = 1209600 SESSION_COOKIE_DOMAIN = None SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_NAME = 'sessionid' SESSION_COOKIE_PATH = '/' SESSION_COOKIE_SAMESITE = 'Lax' SESSION_COOKIE_SECURE = False SESSION_ENGINE = 'django.contrib.sessions.backends.db' SESSION_EXPIRE_AT_BROWSER_CLOSE = False SESSION_FILE_PATH = None SESSION_SAVE_EVERY_REQUEST = False SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer' SETTINGS_MODULE = 'settings' SHORT_DATETIME_FORMAT = 'm/d/Y P' SHORT_DATE_FORMAT = 'm/d/Y' SIGNING_BACKEND = 'django.core.signing.TimestampSigner' SILENCED_SYSTEM_CHECKS = [] SITE_ID = 1 SOCIALACCOUNT_PROVIDERS = {'openid': {'SERVERS': [{'id': 'yahoo', 'name': 'Yahoo', 'openid_url': 'http://me.yahoo.com'}]}, 'google': {'SCOPE': ['profile', 'email'], 'AUTH_PARAMS': {'access_type': 'online'}}, 'facebook': {'METHOD': 'oauth2', 'SCOPE': ['email'], 'FIELDS': ['email', 'name', 'first_name', 'last_name', 'locale', 'timezone'], 'VERSION': 'v2.4'}} STATICFILES_DIRS = [] STATICFILES_FINDERS = "('django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 'compressor.finders.CompressorFinder')" STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage' STATIC_ROOT = '/opt/mailman-web-data/static' STATIC_URL = '/static/' TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': {'context_processors': ['django.template.context_processors.debug', 'django.template.context_processors.i18n', 'django.template.context_processors.media', 'django.template.context_processors.static', 'django.template.context_processors.tz', 'django.template.context_processors.csrf', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'django_mailman3.context_processors.common', 'hyperkitty.context_processors.common', 'postorius.context_processors.postorius']}}] TEST_NON_SERIALIZED_APPS = [] TEST_RUNNER = 'django.test.runner.DiscoverRunner' THOUSAND_SEPARATOR = ',' TIME_FORMAT = 'P' TIME_INPUT_FORMATS = ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'] TIME_ZONE = 'UTC' USE_DEPRECATED_PYTZ = False USE_I18N = True USE_L10N = True USE_SSL = False USE_THOUSAND_SEPARATOR = False USE_TZ = True USE_X_FORWARDED_HOST = True USE_X_FORWARDED_PORT = False WSGI_APPLICATION = 'wsgi.application' X_FRAME_OPTIONS = 'DENY' YEAR_MONTH_FORMAT = 'F Y'
That is my docker-compose.yml: services: postfix: image: boky/postfix #mailu/postfix restart: unless-stopped container_name: postfix #_incomming volumes: - ./data/postfix/etc:/etc/postfix/ #main.cf.d - ./data/core:/opt/mailman ports: - "${MM3_INTERNAL_POSTFIX_SMTP_PORT}:25" - "${MM3_INTERNAL_POSTFIX_SUBM_PORT}:587" environment: - HOSTNAME=${MM3_HOSTNAME} - RELAYHOST=${MM3_RELAYHOST} #- RELAYHOST_USERNAME=${MM3_RELAYHOST_USERNAME} # = An (optional) username for the relay server #- RELAYHOST_PASSWORD=${MM3_RELAYHOST_PASSWORD} # = An (optional) login password for the relay server - POSTFIX_mynetworks=${MM3_POSTFIX_mynetworks} #=127.0.0.0/24,10.8.0.0/24,172.26.0.0/24,192.168.1.0/24 ) #- ALLOWED_SENDER_DOMAINS=${MM3_ALLOWED_SENDER_DOMAINS} # - ALLOW_EMPTY_SENDER_DOMAINS=${MM3_ALLOW_EMPTY_SENDER_DOMAINS} #="true" #'), MM3_ALLOWED_SENDER_DOMAINS can be unset #- MASQUERADED_DOMAINS=${MM3_MASQUERADED_DOMAINS} # = domains where you want to masquerade internal hosts
networks:
mailman:
ipv4_address: ${MM3_IP_INTERNAL_POSTFIX} #172.26.0.5
#services:
mailman-core: image: maxking/mailman-core:0.4 # Use a specific version tag (tag latest is not published) container_name: mailman-core hostname: mailman-core restart: unless-stopped volumes: - ./data/core:/opt/mailman/ stop_grace_period: 30s links: - database:database depends_on: database: condition: service_healthy environment: - DATABASE_URL=postgresql://mailman:mailmanpass@database/mailmandb - DATABASE_TYPE=postgres - DATABASE_CLASS=mailman.database.postgresql.PostgreSQLDatabase - HYPERKITTY_API_KEY=${MM3_HYPERKITTY_API_KEY} #someapikey_longAndTrustworty - TIMEZONE=${MM3_TIMEZONE} #Europe/Berlin - MTA=postfix - SMTP_HOST=172.26.0.5 #postfix # outgoing smtp Sererv - SMTP_PORT=25 #${MM3_INTERNAL_POSTFIX_SMTP_PORT} # Outgoing SMTPS Server Port
ports:
- "8001:8001" # API removed 127.0.0.1
- "8024:8024" # LMTP - incoming emails
#extra_hosts:
# - ${MM3_HOSTNAME}:${MM3_IP_INTERNAL_POSTFIX}
networks:
mailman:
ipv4_address: ${MM3_IP_INTERNAL_CORE} #172.26.0.2
mailman-web: image: maxking/mailman-web:0.4 # Use a specific version tag (tag latest is not published) container_name: mailman-web hostname: mailman-web restart: unless-stopped depends_on: database: condition: service_healthy links: - mailman-core:mailman-core - database:database volumes: - ./data/web:/opt/mailman-web-data environment: - DATABASE_TYPE=postgres - DATABASE_URL=postgresql://mailman:mailmanpass@database/mailmandb - HAYPERKITTY_API_KEY=${MM3_HYPERKITTY_API_KEY} #someapikey_longAndTrustworty - UWSGI_STATIC_MAP=/static=/opt/mailman-web-data/static - SECRET_KEY=${MM3_SECRET_KEY} #blah-blah-secret_undgehie - SERVE_FROM_DOMAIN=${MM3_SERVE_FROM_DOMAIN} #lists.mydomain.net - MAILMAN_ADMIN_USER=${MM3_MAILMAN_ADMIN_USER} #it - MAILMAN_ADMIN_EMAIL=${MM3_MAILMAN_ADMIN_EMAIL} #it@mydomain.net - DJANGO_ALLOWED_HOSTS=${MM3_DJANGO_ALLOWED_HOSTS} #lists.mydomain.net - SMTP_HOST=172.26.0.5 #postfix - SMTP_PORT=25 #${MM3_INTERNAL_POSTFIX_SMTP_PORT} - TIMEZONE=${MM3_TIMEZONE} #Europe/Berlin
ports:
- "8000:8000" # HTTP removed 127.0.0.1
- "8080:8080" # uwsgi
# extra_hosts:
# - ${MM3_HOSTNAME}:${MM3_IP_INTERNAL_POSTFIX}
networks:
mailman:
ipv4_address: ${MM3_IP_INTERNAL_WEB} #172.26.0.3
database: environment: - POSTGRES_DB=mailmandb - POSTGRES_USER=mailman - POSTGRES_PASSWORD=mailmanpass - TIMEZONE=${MM3_TIMEZONE} #Europe/Berlin image: postgres:12-alpine volumes: - ./data/database:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready --dbname mailmandb --username mailman"] interval: 10s timeout: 5s retries: 5 networks: mailman: ipv4_address: ${MM3_IP_INTERNAL_DB} #172.26.0.4
networks: mailman: driver: bridge ipam: driver: default config: - subnet: ${MM3_SUBNET} #172.26.0.0/24
Mailman-extra.cfg: [mailman] site_owner:mailman@mydomain.de max_recipients=1 SMTP_MAX_RCPTS = 1 run_tasks_every: 1h
VERP_CONFIRMATIONS = Yes VERP_PASSWORD_REMINDERS = Yes VERP_PERSONALIZED_DELIVERIES = Yes VERP_DELIVERY_INTERVAL = 1 VERP_PROBES: Yes [devmode] enabled: no recipient:it@mydomain.de # # extra local settings for mailmen [mta] incoming: mailman.mta.postfix.LMTP outgoing: mailman.mta.deliver.deliver lmtp_host: 172.26.0.2 lmtp_port: 8024 smtp_host: 172.26.0.5 smtp_port: 25 #configuration: /etc/postfix-mailman.cfg
# # # [logging.smtp] level: warn
[language.en] charset: utf-8
[language.de] charset: utf-8
and my settings_locale.py from mailman-web:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = '172.26.0.5' EMAIL_PORT = 25 USE_SSL = False DEFAULT_FROM_EMAIL ="lists@mydomain.net" SERVER_EMAIL ="lists@mydomain.net"
#DEBUG = True
#: Default list of admins who receive the emails from error logging. ADMINS = ( ('Mailman Suite Admin', 'it@mydomain.net'), )
On 1/21/25 05:44, Helge Baumgart wrote:
Hyperkitty-Api-Key in the docker-compose.yml is set via .env Variabel, so it should be identical.
I don't know how this works in the Docker image, but ...
Traceback (most recent call last): File "/usr/lib/python3.11/site-packages/django/core/handlers/exception.py", line 56, in inner response = get_response(request) File "/usr/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/usr/lib/python3.11/site-packages/hyperkitty/views/mailman.py", line 109, in _decorator not hmac.compare_digest(
Exception Type: TypeError at /hyperkitty/api/mailman/urls Exception Value: unsupported operand types(s) or combination of types: 'str' and 'NoneType'
The above code is doing
auth = authorization.split()
if (len(auth) != 2 or auth[0] != 'Token' or
not hmac.compare_digest(
auth[1], settings.MAILMAN_ARCHIVER_KEY)):
and the exception says either auth[0] is None or auth[1] or settings.MAILMAN_ARCHIVER_KEY is None.
But
META: ... HTTP_AUTHORIZATION = 'Token (value)' and
Settings: Using settings module settings ... MAILMAN_ARCHIVER_KEY = '********************'
So The Authorization header is the appropriate Token value
which
should result in auth[0] being 'Token', auth[1] being the value and
MAILMAN_ARCHIVER_KEY is set
That is my docker-compose.yml: ... mailman-web: ... - HAYPERKITTY_API_KEY=${MM3_HYPERKITTY_API_KEY} #someapikey_longAndTrustworty
I don't really understand why the above typo (HAYPERKITTY_API_KEY, not HYPERKITTY_API_KEY) would cause this error, but it needs to be fixed.
-- Mark Sapiro <mark@msapiro.net> The highway is for gamblers, San Francisco Bay Area, California better use your sense - B. Dylan
Hello Mark,
THANK You for identifying MY typos.... how embarrassing. :-) Now ist running like a charm. It's always the same...
These Variables are setting the internal Values via the docker-compose.yml. If they do not match, the internal variables are not set. Therefor my typo H*A*YPERKITTY_API_KEY =! HYPERKITTY_API_KEY caused, that the mailman-web section of the docker-compose.yml had NO Hyperkitty API- KEY. I suspected something like that, that's why i set the key via the .env variabels to ensure identical values in all sections oft the docker.compose.yml. I didn't check the name of the variables...
Thx again!
Best wishes Helge
Ps.:
That docker-compose.yml with the settings_locale.py and mailman_extra.cfg basically setts a complete deployable environment INCLUDING the MTA, which is independent of the host...
Am 22.01.2025 um 06:36 schrieb Mark Sapiro:
On 1/21/25 05:44, Helge Baumgart wrote:
Hyperkitty-Api-Key in the docker-compose.yml is set via .env Variabel, so it should be identical.
I don't know how this works in the Docker image, but ...
Traceback (most recent call last): File "/usr/lib/python3.11/site-packages/django/core/handlers/exception.py", line 56, in inner response = get_response(request) File "/usr/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/usr/lib/python3.11/site-packages/hyperkitty/views/mailman.py", line 109, in _decorator not hmac.compare_digest(
Exception Type: TypeError at /hyperkitty/api/mailman/urls Exception Value: unsupported operand types(s) or combination of types: 'str' and 'NoneType'
The above code is doing
auth = authorization.split() if (len(auth) != 2 or auth[0] != 'Token' or not hmac.compare_digest( auth[1], settings.MAILMAN_ARCHIVER_KEY)):
and the exception says either auth[0] is None or auth[1] or settings.MAILMAN_ARCHIVER_KEY is None.
But
META: ... HTTP_AUTHORIZATION = 'Token (value)' and
Settings: Using settings module settings ... MAILMAN_ARCHIVER_KEY = '********************'
So The Authorization header is the appropriate
Token value
which should result in auth[0] being 'Token', auth[1] being the value and MAILMAN_ARCHIVER_KEY is setThat is my docker-compose.yml: ... mailman-web: ... - HAYPERKITTY_API_KEY=${MM3_HYPERKITTY_API_KEY} #someapikey_longAndTrustworty
I don't really understand why the above typo (HAYPERKITTY_API_KEY, not HYPERKITTY_API_KEY) would cause this error, but it needs to be fixed.
participants (3)
-
Helge Baumgart
-
Mark Sapiro
-
Stephen J. Turnbull