1 import os

2 from pathlib import Path

3

4 import structlog

5 from dotenv import load_dotenv

6

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

8

9 load_dotenv()

10

11 logger = structlog.get_logger(__name__)

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

13 BASE_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!

20 SECRET_KEY = os.getenv("MESHSERVER_SECRET_KEY")

21

22

23 def str2bool(v):

24 return v.lower() in (

25 "yes",

26 "true",

27 "t",

28 "1",

29 )

30

31

32 USE_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!

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

36

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

38 CSRF_TRUSTED_ORIGINS = os.getenv(

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

40).split(",")

41

42# Application definition

43

44 INSTALLED_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 MIDDLEWARE = [

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

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

78

79 TEMPLATES = [

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

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

97

98

99# Database

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

101

102 DATABASES = {

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

113 AUTH_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

131 LANGUAGE_CODE = "en-us"

132

133 TIME_ZONE = "Europe/Zurich"

134

135 USE_I18N = True

136

137 USE_TZ = True

138

139# Static files (CSS, JavaScript, Images)

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

141

142 STATIC_URL = "static/"

143

144# Default primary key field type

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

146

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

148

149 STATIC_ROOT = BASE_DIR / "staticfiles"

150

151 STORAGES = {

152 # ...

153 "staticfiles": {

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

155 },

156}

157

158 STATICFILES_DIRS = [BASE_DIR / "static"]

159

160 AUTHENTICATION_BACKENDS = [

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

162 "allauth.account.auth_backends.AuthenticationBackend",

163]

164

165

166 SOCIALACCOUNT_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}

184 SITE_ID = 1

185 ACCOUNT_EMAIL_VERIFICATION = "none"

186 LOGIN_REDIRECT_URL = "/"

187 ACCOUNT_LOGOUT_ON_GET = True

188 SOCIALACCOUNT_LOGIN_ON_GET = True

189 SOCIALACCOUNT_ONLY = True

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

191

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

193 COTTON_DIR = "components"

194

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

196

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

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

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

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

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

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

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

204

205 PAGINATION_PER_PAGE = 25

206

207# Logging

208# configure_structlog()

209# LOGGING = setup_logging()