Update urls.py + settings.py
- modify paths to match package patches - add SAML configuration Signed-off-by: Georg Pfuetzenreuter <mail@georg-pfuetzenreuter.net>
This commit is contained in:
		
							parent
							
								
									86bc48f3e0
								
							
						
					
					
						commit
						7819d7980b
					
				@ -12,9 +12,12 @@ import sentry_sdk
 | 
			
		||||
from pydantic import AnyUrl, BaseSettings, EmailStr, Field, validator
 | 
			
		||||
from sentry_sdk.integrations.django import DjangoIntegration
 | 
			
		||||
 | 
			
		||||
from takahe import __version__
 | 
			
		||||
from takahe.takahe import __version__
 | 
			
		||||
 | 
			
		||||
BASE_DIR = Path(__file__).resolve().parent.parent
 | 
			
		||||
import saml2
 | 
			
		||||
from saml2.saml import NAMEID_FORMAT_PERSISTENT
 | 
			
		||||
 | 
			
		||||
BASE_DIR = '/srv/takahe'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CacheBackendUrl(AnyUrl):
 | 
			
		||||
@ -59,10 +62,10 @@ class Settings(BaseSettings):
 | 
			
		||||
 | 
			
		||||
    #: The currently running environment, used for things such as sentry
 | 
			
		||||
    #: error reporting.
 | 
			
		||||
    ENVIRONMENT: Environments = "development"
 | 
			
		||||
    ENVIRONMENT: Environments = "production"
 | 
			
		||||
 | 
			
		||||
    #: Should django run in debug mode?
 | 
			
		||||
    DEBUG: bool = False
 | 
			
		||||
    DEBUG: bool = True
 | 
			
		||||
 | 
			
		||||
    #: Set a secret key used for signing values such as sessions. Randomized
 | 
			
		||||
    #: by default, so you'll logout everytime the process restarts.
 | 
			
		||||
@ -99,7 +102,7 @@ class Settings(BaseSettings):
 | 
			
		||||
    ERROR_EMAILS: list[EmailStr] | None = None
 | 
			
		||||
 | 
			
		||||
    MEDIA_URL: str = "/media/"
 | 
			
		||||
    MEDIA_ROOT: str = str(BASE_DIR / "media")
 | 
			
		||||
    MEDIA_ROOT: str = os.path.join(BASE_DIR, "media")
 | 
			
		||||
    MEDIA_BACKEND: MediaBackendUrl | None = None
 | 
			
		||||
 | 
			
		||||
    #: Maximum filesize when uploading images. Increasing this may increase memory utilization
 | 
			
		||||
@ -147,7 +150,7 @@ class Settings(BaseSettings):
 | 
			
		||||
 | 
			
		||||
    class Config:
 | 
			
		||||
        env_prefix = "TAKAHE_"
 | 
			
		||||
        env_file = str(BASE_DIR / TAKAHE_ENV_FILE)
 | 
			
		||||
        env_file = '/etc/sysconfig/takahe'
 | 
			
		||||
        env_file_encoding = "utf-8"
 | 
			
		||||
        # Case sensitivity doesn't work on Windows, so might as well be
 | 
			
		||||
        # consistent from the get-go.
 | 
			
		||||
@ -179,16 +182,17 @@ INSTALLED_APPS = [
 | 
			
		||||
    "django.contrib.staticfiles",
 | 
			
		||||
    "django_htmx",
 | 
			
		||||
    "corsheaders",
 | 
			
		||||
    "core",
 | 
			
		||||
    "activities",
 | 
			
		||||
    "api",
 | 
			
		||||
    "mediaproxy",
 | 
			
		||||
    "stator",
 | 
			
		||||
    "users",
 | 
			
		||||
    "takahe.core",
 | 
			
		||||
    "takahe.activities",
 | 
			
		||||
    "takahe.api",
 | 
			
		||||
    "takahe.mediaproxy",
 | 
			
		||||
    "takahe.stator",
 | 
			
		||||
    "takahe.users",
 | 
			
		||||
    "djangosaml2",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
MIDDLEWARE = [
 | 
			
		||||
    "core.middleware.SentryTaggingMiddleware",
 | 
			
		||||
    "takahe.core.middleware.SentryTaggingMiddleware",
 | 
			
		||||
    "django.middleware.security.SecurityMiddleware",
 | 
			
		||||
    "corsheaders.middleware.CorsMiddleware",
 | 
			
		||||
    "whitenoise.middleware.WhiteNoiseMiddleware",
 | 
			
		||||
@ -199,19 +203,20 @@ MIDDLEWARE = [
 | 
			
		||||
    "django.contrib.messages.middleware.MessageMiddleware",
 | 
			
		||||
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
 | 
			
		||||
    "django_htmx.middleware.HtmxMiddleware",
 | 
			
		||||
    "core.middleware.HeadersMiddleware",
 | 
			
		||||
    "core.middleware.ConfigLoadingMiddleware",
 | 
			
		||||
    "api.middleware.ApiTokenMiddleware",
 | 
			
		||||
    "users.middleware.IdentityMiddleware",
 | 
			
		||||
    "activities.middleware.EmojiDefaultsLoadingMiddleware",
 | 
			
		||||
    "takahe.core.middleware.HeadersMiddleware",
 | 
			
		||||
    "takahe.core.middleware.ConfigLoadingMiddleware",
 | 
			
		||||
    "takahe.api.middleware.ApiTokenMiddleware",
 | 
			
		||||
    "takahe.users.middleware.IdentityMiddleware",
 | 
			
		||||
    "takahe.activities.middleware.EmojiDefaultsLoadingMiddleware",
 | 
			
		||||
    "djangosaml2.middleware.SamlSessionMiddleware",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
ROOT_URLCONF = "takahe.urls"
 | 
			
		||||
ROOT_URLCONF = "takahe.takahe.urls"
 | 
			
		||||
 | 
			
		||||
TEMPLATES = [
 | 
			
		||||
    {
 | 
			
		||||
        "BACKEND": "django.template.backends.django.DjangoTemplates",
 | 
			
		||||
        "DIRS": [BASE_DIR / "templates"],
 | 
			
		||||
        "DIRS": [os.path.join(BASE_DIR, "templates")],
 | 
			
		||||
        "APP_DIRS": True,
 | 
			
		||||
        "OPTIONS": {
 | 
			
		||||
            "context_processors": [
 | 
			
		||||
@ -219,13 +224,13 @@ TEMPLATES = [
 | 
			
		||||
                "django.template.context_processors.request",
 | 
			
		||||
                "django.contrib.auth.context_processors.auth",
 | 
			
		||||
                "django.contrib.messages.context_processors.messages",
 | 
			
		||||
                "core.context.config_context",
 | 
			
		||||
                "takahe.core.context.config_context",
 | 
			
		||||
            ],
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
WSGI_APPLICATION = "takahe.wsgi.application"
 | 
			
		||||
WSGI_APPLICATION = "takahe.takahe.wsgi.application"
 | 
			
		||||
 | 
			
		||||
if SETUP.DATABASE_SERVER:
 | 
			
		||||
    DATABASES = {
 | 
			
		||||
@ -272,7 +277,7 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
 | 
			
		||||
 | 
			
		||||
AUTH_USER_MODEL = "users.User"
 | 
			
		||||
 | 
			
		||||
LOGIN_URL = "/auth/login/"
 | 
			
		||||
LOGIN_URL = "/saml2/login/"
 | 
			
		||||
LOGOUT_URL = "/auth/logout/"
 | 
			
		||||
LOGIN_REDIRECT_URL = "/"
 | 
			
		||||
LOGOUT_REDIRECT_URL = "/"
 | 
			
		||||
@ -282,7 +287,7 @@ STATICFILES_FINDERS = [
 | 
			
		||||
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
STATICFILES_DIRS = [BASE_DIR / "static"]
 | 
			
		||||
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
 | 
			
		||||
 | 
			
		||||
STATICFILES_STORAGE = "django.contrib.staticfiles.storage.ManifestStaticFilesStorage"
 | 
			
		||||
 | 
			
		||||
@ -290,7 +295,7 @@ SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
 | 
			
		||||
 | 
			
		||||
WHITENOISE_MAX_AGE = 3600
 | 
			
		||||
 | 
			
		||||
STATIC_ROOT = BASE_DIR / "static-collected"
 | 
			
		||||
STATIC_ROOT = os.path.join(BASE_DIR, "static-collected")
 | 
			
		||||
 | 
			
		||||
ALLOWED_HOSTS = SETUP.ALLOWED_HOSTS
 | 
			
		||||
 | 
			
		||||
@ -355,14 +360,14 @@ if SETUP.MEDIA_BACKEND:
 | 
			
		||||
    parsed = urllib.parse.urlparse(SETUP.MEDIA_BACKEND)
 | 
			
		||||
    query = urllib.parse.parse_qs(parsed.query)
 | 
			
		||||
    if parsed.scheme == "gs":
 | 
			
		||||
        DEFAULT_FILE_STORAGE = "core.uploads.TakaheGoogleCloudStorage"
 | 
			
		||||
        DEFAULT_FILE_STORAGE = "takahe.core.uploads.TakaheGoogleCloudStorage"
 | 
			
		||||
        GS_BUCKET_NAME = parsed.path.lstrip("/")
 | 
			
		||||
        GS_QUERYSTRING_AUTH = False
 | 
			
		||||
        if parsed.hostname is not None:
 | 
			
		||||
            port = parsed.port or 443
 | 
			
		||||
            GS_CUSTOM_ENDPOINT = f"https://{parsed.hostname}:{port}"
 | 
			
		||||
    elif parsed.scheme == "s3":
 | 
			
		||||
        DEFAULT_FILE_STORAGE = "core.uploads.TakaheS3Storage"
 | 
			
		||||
        DEFAULT_FILE_STORAGE = "takahe.core.uploads.TakaheS3Storage"
 | 
			
		||||
        AWS_STORAGE_BUCKET_NAME = parsed.path.lstrip("/")
 | 
			
		||||
        AWS_QUERYSTRING_AUTH = False
 | 
			
		||||
        AWS_DEFAULT_ACL = "public-read"
 | 
			
		||||
@ -393,3 +398,97 @@ TAKAHE_USER_AGENT = (
 | 
			
		||||
    f"python-httpx/{httpx.__version__} "
 | 
			
		||||
    f"(Takahe/{__version__}; +https://{SETUP.MAIN_DOMAIN}/)"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
AUTHENTICATION_BACKENDS = (
 | 
			
		||||
    'django.contrib.auth.backends.ModelBackend',
 | 
			
		||||
    'djangosaml2.backends.Saml2Backend',
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
SAML_SESSION_COOKIE_NAME = 'takahe_test_session'
 | 
			
		||||
SESSION_COOKIE_SECURE = False
 | 
			
		||||
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
 | 
			
		||||
SAML_DJANGO_USER_MAIN_ATTRIBUTE = 'email'
 | 
			
		||||
 | 
			
		||||
SAML_ATTRIBUTE_MAPPING = {
 | 
			
		||||
    'email': ('email', ),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SAML_CONFIG = {
 | 
			
		||||
  # full path to the xmlsec1 binary programm
 | 
			
		||||
  'xmlsec_binary': '/usr/bin/xmlsec1',
 | 
			
		||||
 | 
			
		||||
  # your entity id, usually your subdomain plus the url to the metadata view
 | 
			
		||||
  'entityid': 'https://__REPLACE_ME__/saml2/metadata/',
 | 
			
		||||
 | 
			
		||||
  'attribute_map_dir': os.path.join(BASE_DIR, 'attribute-maps'),
 | 
			
		||||
 | 
			
		||||
  'allow_unknown_attributes': False,
 | 
			
		||||
 | 
			
		||||
  'service': {
 | 
			
		||||
      'sp' : {
 | 
			
		||||
          'name': 'Federated Takahe sample SP',
 | 
			
		||||
          'name_id_format': saml2.saml.NAMEID_FORMAT_PERSISTENT,
 | 
			
		||||
 | 
			
		||||
          'endpoints': {
 | 
			
		||||
              'assertion_consumer_service': [
 | 
			
		||||
                  ('https://__REPLACE_ME__/saml2/acs/',
 | 
			
		||||
                   saml2.BINDING_HTTP_POST),
 | 
			
		||||
                  ],
 | 
			
		||||
              'single_logout_service': [
 | 
			
		||||
                  ('https://__REPLACE_ME__/saml2/ls/',
 | 
			
		||||
                   saml2.BINDING_HTTP_REDIRECT),
 | 
			
		||||
                  ('https://__REPLACE_ME__/saml2/ls/post',
 | 
			
		||||
                   saml2.BINDING_HTTP_POST),
 | 
			
		||||
                  ],
 | 
			
		||||
              },
 | 
			
		||||
 | 
			
		||||
          'signing_algorithm':  saml2.xmldsig.SIG_RSA_SHA256,
 | 
			
		||||
          'digest_algorithm':  saml2.xmldsig.DIGEST_SHA256,
 | 
			
		||||
 | 
			
		||||
          'force_authn': False,
 | 
			
		||||
 | 
			
		||||
          'name_id_format_allow_create': False,
 | 
			
		||||
 | 
			
		||||
          'required_attributes': ['uid',
 | 
			
		||||
                                  'email'],
 | 
			
		||||
 | 
			
		||||
          'want_response_signed': True,
 | 
			
		||||
          'authn_requests_signed': True,
 | 
			
		||||
          'logout_requests_signed': True,
 | 
			
		||||
          'want_assertions_signed': True,
 | 
			
		||||
 | 
			
		||||
          'only_use_keys_in_metadata': True,
 | 
			
		||||
 | 
			
		||||
          'allow_unsolicited': False,
 | 
			
		||||
 | 
			
		||||
  'metadata': {
 | 
			
		||||
# in production, use local file
 | 
			
		||||
#      'local': [os.path.join(BASE_DIR, 'remote_metadata.xml')],
 | 
			
		||||
      'remote': [{"url": "https://libsso.net/realms/LibertaCasa/protocol/saml/descriptor"},],
 | 
			
		||||
      },
 | 
			
		||||
 | 
			
		||||
  'debug': 1,
 | 
			
		||||
 | 
			
		||||
  'key_file': '__REPLACE_ME__',  # private part
 | 
			
		||||
  'cert_file': '__REPLACE_ME__',  # public part
 | 
			
		||||
 | 
			
		||||
  # Encryption
 | 
			
		||||
#  'encryption_keypairs': [{
 | 
			
		||||
#      'key_file': '__REPLACE_ME__',  # private part
 | 
			
		||||
#      'cert_file': '__REPLACE_ME__',  # public part
 | 
			
		||||
#  }],
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LOGGING = {
 | 
			
		||||
    'version': 1,
 | 
			
		||||
    'disable_existing_loggers': False,
 | 
			
		||||
    'handlers': {
 | 
			
		||||
        'console': {
 | 
			
		||||
            'class': 'logging.StreamHandler',
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    'root': {
 | 
			
		||||
        'handlers': ['console'],
 | 
			
		||||
        'level': 'DEBUG',
 | 
			
		||||
    },
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,9 @@ from mediaproxy import views as mediaproxy
 | 
			
		||||
from stator import views as stator
 | 
			
		||||
from users.views import activitypub, admin, auth, identity, report, settings
 | 
			
		||||
 | 
			
		||||
from django.conf.urls import include
 | 
			
		||||
from django.views.generic.base import RedirectView
 | 
			
		||||
 | 
			
		||||
urlpatterns = [
 | 
			
		||||
    path("", core.homepage),
 | 
			
		||||
    path("manifest.json", core.AppManifest.as_view()),
 | 
			
		||||
@ -174,7 +177,7 @@ urlpatterns = [
 | 
			
		||||
    path("@<handle>/posts/<int:post_id>/report/", report.SubmitReport.as_view()),
 | 
			
		||||
    path("@<handle>/posts/<int:post_id>/edit/", compose.Compose.as_view()),
 | 
			
		||||
    # Authentication
 | 
			
		||||
    path("auth/login/", auth.Login.as_view(), name="login"),
 | 
			
		||||
    path("auth/login/", RedirectView.as_view(url='/saml2/login', permanent=False), name='login'),
 | 
			
		||||
    path("auth/logout/", auth.Logout.as_view(), name="logout"),
 | 
			
		||||
    path("auth/signup/", auth.Signup.as_view(), name="signup"),
 | 
			
		||||
    path("auth/reset/", auth.TriggerReset.as_view(), name="trigger_reset"),
 | 
			
		||||
@ -248,4 +251,5 @@ urlpatterns = [
 | 
			
		||||
        core.custom_static_serve,
 | 
			
		||||
        kwargs={"document_root": djsettings.MEDIA_ROOT},
 | 
			
		||||
    ),
 | 
			
		||||
    path('saml2/', include('djangosaml2.urls')),
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user