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

54 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-09 15:09 +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 

62MIDDLEWARE = [ 

63 "django_structlog.middlewares.RequestMiddleware", 

64 "whitenoise.middleware.WhiteNoiseMiddleware", 

65 "django.middleware.security.SecurityMiddleware", 

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

67 "django.middleware.common.CommonMiddleware", 

68 "django.middleware.csrf.CsrfViewMiddleware", 

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

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

71 "django.middleware.clickjacking.XFrameOptionsMiddleware", 

72 "allauth.account.middleware.AccountMiddleware", 

73 "django_htmx.middleware.HtmxMiddleware", 

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

75] 

76 

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

78 

79TEMPLATES = [ 

80 { 

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

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

83 "APP_DIRS": True, 

84 "OPTIONS": { 

85 "context_processors": [ 

86 "django.template.context_processors.debug", 

87 "django.template.context_processors.request", 

88 "django.contrib.auth.context_processors.auth", 

89 "django.contrib.messages.context_processors.messages", 

90 ], 

91 }, 

92 }, 

93] 

94 

95 

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

97 

98 

99# Database 

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

101 

102DATABASES = { 

103 "default": { 

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

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

106 } 

107} 

108 

109 

110# Password validation 

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

112 

113AUTH_PASSWORD_VALIDATORS = [ 

114 { 

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

116 }, 

117 { 

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

119 }, 

120 { 

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

122 }, 

123 { 

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

125 }, 

126] 

127 

128# Internationalization 

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

130 

131LANGUAGE_CODE = "en-us" 

132 

133TIME_ZONE = "Europe/Zurich" 

134 

135USE_I18N = True 

136 

137USE_TZ = True 

138 

139# Static files (CSS, JavaScript, Images) 

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

141 

142STATIC_URL = "static/" 

143 

144# Default primary key field type 

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

146 

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

148 

149STATIC_ROOT = BASE_DIR / "staticfiles" 

150 

151STORAGES = { 

152 # ... 

153 "staticfiles": { 

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

155 }, 

156} 

157 

158STATICFILES_DIRS = [BASE_DIR / "static"] 

159 

160AUTHENTICATION_BACKENDS = [ 

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

162 "allauth.account.auth_backends.AuthenticationBackend", 

163] 

164 

165 

166SOCIALACCOUNT_PROVIDERS = { 

167 "openid_connect": { 

168 "APPS": [ 

169 { 

170 "provider_id": "keycloak", 

171 "name": "Keycloak", 

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

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

174 "settings": { 

175 "server_url": os.getenv( 

176 "KEYCLOAK_SERVER_URL", 

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

178 ), 

179 }, 

180 } 

181 ] 

182 } 

183} 

184SITE_ID = 1 

185ACCOUNT_EMAIL_VERIFICATION = "none" 

186LOGIN_REDIRECT_URL = "/" 

187ACCOUNT_LOGOUT_ON_GET = True 

188SOCIALACCOUNT_LOGIN_ON_GET = True 

189SOCIALACCOUNT_ONLY = True 

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

191ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https" 

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" 

205KEYCLOAK_ALLOWED_CLIENTS = os.getenv("KEYCLOAK_ALLOWED_CLIENTS", "meshadmin-cli").split( 

206 "," 

207) 

208 

209PAGINATION_PER_PAGE = 25 

210 

211# Logging 

212configure_structlog() 

213LOGGING = setup_logging()