Coverage for src/meshadmin/server/project/settings/base.py: 100%

52 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-04-10 16:08 +0200

1import os 

2from pathlib import Path 

3 

4import structlog 

5from dotenv import load_dotenv 

6 

7from meshadmin.server.project.logging import configure_structlog, setup_logging 

8 

9load_dotenv() 

10 

11logger = structlog.get_logger(__name__) 

12# Build paths inside the project like this: BASE_DIR / 'subdir'. 

13BASE_DIR = Path(__file__).resolve().parent.parent.parent 

14 

15 

16# Quick-start development settings - unsuitable for production 

17# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/ 

18 

19# SECURITY WARNING: keep the secret key used in production secret! 

20SECRET_KEY = os.getenv("MESHSERVER_SECRET_KEY") 

21 

22 

23def str2bool(v): 

24 return v.lower() in ( 

25 "yes", 

26 "true", 

27 "t", 

28 "1", 

29 ) 

30 

31 

32USE_X_FORWARDED_HOST = str2bool(os.getenv("MESHSERVER_USE_X_FORWARDED_HOST", "False")) 

33 

34# SECURITY WARNING: don't run with debug turned on in production! 

35DEBUG = str2bool(os.getenv("MESHSERVER_DEBUG", "False")) 

36 

37ALLOWED_HOSTS = os.getenv("MESHSERVER_ALLOWED_HOSTS", "localhost").split(",") 

38CSRF_TRUSTED_ORIGINS = os.getenv( 

39 "MESHSERVER_CSRF_TRUSTED_ORIGINS", "http://localhost:8000" 

40).split(",") 

41 

42# Application definition 

43 

44INSTALLED_APPS = [ 

45 "django.contrib.admin", 

46 "django.contrib.auth", 

47 "django.contrib.contenttypes", 

48 "django.contrib.sessions", 

49 "django.contrib.messages", 

50 "django.contrib.staticfiles", 

51 "meshadmin.server.networks", 

52 "allauth", 

53 "allauth.account", 

54 "allauth.socialaccount", 

55 "allauth.socialaccount.providers.openid_connect", 

56 "django_tailwind_cli", 

57 "django_cotton", 

58 "django_htmx", 

59 "django.contrib.sites", 

60] 

61 

62# Add django-structlog middleware 

63MIDDLEWARE = [ 

64 "django_structlog.middlewares.RequestMiddleware", 

65 "whitenoise.middleware.WhiteNoiseMiddleware", 

66 "django.middleware.security.SecurityMiddleware", 

67 "django.contrib.sessions.middleware.SessionMiddleware", 

68 "django.middleware.common.CommonMiddleware", 

69 "django.middleware.csrf.CsrfViewMiddleware", 

70 "django.contrib.auth.middleware.AuthenticationMiddleware", 

71 "django.contrib.messages.middleware.MessageMiddleware", 

72 "django.middleware.clickjacking.XFrameOptionsMiddleware", 

73 "allauth.account.middleware.AccountMiddleware", 

74 "django_htmx.middleware.HtmxMiddleware", 

75 "meshadmin.server.project.middleware.BreadcrumbMiddleware", 

76] 

77 

78ROOT_URLCONF = "meshadmin.server.project.urls" 

79 

80TEMPLATES = [ 

81 { 

82 "BACKEND": "django.template.backends.django.DjangoTemplates", 

83 "DIRS": [BASE_DIR / "templates"], 

84 "APP_DIRS": True, 

85 "OPTIONS": { 

86 "context_processors": [ 

87 "django.template.context_processors.debug", 

88 "django.template.context_processors.request", 

89 "django.contrib.auth.context_processors.auth", 

90 "django.contrib.messages.context_processors.messages", 

91 ], 

92 }, 

93 }, 

94] 

95 

96 

97WSGI_APPLICATION = "meshadmin.server.project.wsgi.application" 

98 

99 

100# Database 

101# https://docs.djangoproject.com/en/5.1/ref/settings/#databases 

102 

103DATABASES = { 

104 "default": { 

105 "ENGINE": "django.db.backends.sqlite3", 

106 "NAME": os.getenv("MESHSERVER_SQLITE_PATH", "db.sqlite3"), 

107 } 

108} 

109 

110 

111# Password validation 

112# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators 

113 

114AUTH_PASSWORD_VALIDATORS = [ 

115 { 

116 "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", 

117 }, 

118 { 

119 "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", 

120 }, 

121 { 

122 "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", 

123 }, 

124 { 

125 "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", 

126 }, 

127] 

128 

129# Internationalization 

130# https://docs.djangoproject.com/en/5.1/topics/i18n/ 

131 

132LANGUAGE_CODE = "en-us" 

133 

134TIME_ZONE = "Europe/Zurich" 

135 

136USE_I18N = True 

137 

138USE_TZ = True 

139 

140# Static files (CSS, JavaScript, Images) 

141# https://docs.djangoproject.com/en/5.1/howto/static-files/ 

142 

143STATIC_URL = "static/" 

144 

145# Default primary key field type 

146# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field 

147 

148DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" 

149 

150STATIC_ROOT = BASE_DIR / "staticfiles" 

151 

152STORAGES = { 

153 # ... 

154 "staticfiles": { 

155 "BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage", 

156 }, 

157} 

158 

159STATICFILES_DIRS = [BASE_DIR / "static"] 

160 

161AUTHENTICATION_BACKENDS = [ 

162 "django.contrib.auth.backends.ModelBackend", 

163 "allauth.account.auth_backends.AuthenticationBackend", 

164] 

165 

166 

167SOCIALACCOUNT_PROVIDERS = { 

168 "openid_connect": { 

169 "APPS": [ 

170 { 

171 "provider_id": "keycloak", 

172 "name": "Keycloak", 

173 "client_id": os.getenv("KEYCLOAK_CLIENT_ID", "meshadmin"), 

174 "secret": os.getenv("KEYCLOAK_CLIENT_SECRET", ""), 

175 "settings": { 

176 "server_url": os.getenv( 

177 "KEYCLOAK_SERVER_URL", 

178 "http://localhost:8080/realms/meshadmin/.well-known/openid-configuration", 

179 ), 

180 }, 

181 } 

182 ] 

183 } 

184} 

185SITE_ID = 1 

186ACCOUNT_EMAIL_VERIFICATION = "none" 

187LOGIN_REDIRECT_URL = "/" 

188ACCOUNT_LOGOUT_ON_GET = True 

189SOCIALACCOUNT_LOGIN_ON_GET = True 

190SOCIALACCOUNT_ONLY = True 

191LOGIN_URL = "/accounts/oidc/keycloak/login/?process=login" 

192 

193# https://django-cotton.com/docs/configuration 

194COTTON_DIR = "components" 

195 

196MESH_SERVER_URL = os.getenv("MESH_SERVER_URL", "http://localhost:8000") 

197 

198KEYCLOAK_BASE_URL = os.getenv("KEYCLOAK_BASE_URL", "http://localhost:8080") 

199KEYCLOAK_REALM = os.getenv("KEYCLOAK_REALM", "meshadmin") 

200KEYCLOAK_ADMIN_CLIENT = os.getenv("KEYCLOAK_ADMIN_CLIENT", "admin-cli") 

201KEYCLOAK_ISSUER = f"{KEYCLOAK_BASE_URL}/realms/{KEYCLOAK_REALM}" 

202KEYCLOAK_DEVICE_AUTH_URL = f"{KEYCLOAK_ISSUER}/protocol/openid-connect/auth/device" 

203KEYCLOAK_TOKEN_URL = f"{KEYCLOAK_ISSUER}/protocol/openid-connect/token" 

204KEYCLOAK_CERTS_URL = f"{KEYCLOAK_ISSUER}/protocol/openid-connect/certs" 

205 

206PAGINATION_PER_PAGE = 25 

207 

208# Logging 

209configure_structlog() 

210LOGGING = setup_logging()