Coverage for config.py: 97%

65 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-02-22 00:11 +0000

1# -*- coding: utf-8 -*- 

2""" 

3Configuration overrides for settings.py 

4""" 

5 

6import os 

7import sys 

8from django.urls import reverse_lazy 

9from django.utils.translation import gettext_lazy as _ 

10from django.contrib.messages import constants as message_constants 

11from ivatar.settings import BASE_DIR 

12 

13from ivatar.settings import MIDDLEWARE 

14from ivatar.settings import INSTALLED_APPS 

15from ivatar.settings import TEMPLATES 

16 

17ADMIN_USERS = [] 

18ALLOWED_HOSTS = ["*"] 

19 

20INSTALLED_APPS.extend( 

21 [ 

22 "django_extensions", 

23 "django_openid_auth", 

24 "bootstrap4", 

25 "anymail", 

26 "ivatar", 

27 "ivatar.ivataraccount", 

28 "ivatar.tools", 

29 ] 

30) 

31 

32MIDDLEWARE.extend( 

33 [ 

34 "django.middleware.locale.LocaleMiddleware", 

35 ] 

36) 

37MIDDLEWARE.insert( 

38 0, 

39 "ivatar.middleware.MultipleProxyMiddleware", 

40) 

41 

42AUTHENTICATION_BACKENDS = ( 

43 # Enable this to allow LDAP authentication. 

44 # See INSTALL for more information. 

45 # 'django_auth_ldap.backend.LDAPBackend', 

46 "django_openid_auth.auth.OpenIDBackend", 

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

48) 

49 

50TEMPLATES[0]["DIRS"].extend( 

51 [ 

52 os.path.join(BASE_DIR, "templates"), 

53 ] 

54) 

55TEMPLATES[0]["OPTIONS"]["context_processors"].append( 

56 "ivatar.context_processors.basepage", 

57) 

58 

59OPENID_CREATE_USERS = True 

60OPENID_UPDATE_DETAILS_FROM_SREG = True 

61 

62SITE_NAME = os.environ.get("SITE_NAME", "libravatar") 

63IVATAR_VERSION = "1.7.0" 

64 

65SCHEMAROOT = "https://www.libravatar.org/schemas/export/0.2" 

66 

67SECURE_BASE_URL = os.environ.get( 

68 "SECURE_BASE_URL", "https://avatars.linux-kernel.at/avatar/" 

69) 

70BASE_URL = os.environ.get("BASE_URL", "http://avatars.linux-kernel.at/avatar/") 

71 

72LOGIN_REDIRECT_URL = reverse_lazy("profile") 

73MAX_LENGTH_EMAIL = 254 # http://stackoverflow.com/questions/386294 

74 

75MAX_NUM_PHOTOS = 5 

76MAX_NUM_UNCONFIRMED_EMAILS = 5 

77MAX_PHOTO_SIZE = 10485760 # in bytes 

78MAX_PIXELS = 7000 

79AVATAR_MAX_SIZE = 512 

80JPEG_QUALITY = 85 

81 

82# I'm not 100% sure if single character domains are possible 

83# under any tld... so MIN_LENGTH_EMAIL/_URL, might be +1 

84MIN_LENGTH_URL = 11 # eg. http://a.io 

85MAX_LENGTH_URL = 255 # MySQL can't handle more than that (LP: 1018682) 

86MIN_LENGTH_EMAIL = 6 # eg. x@x.xx 

87MAX_LENGTH_EMAIL = 254 # http://stackoverflow.com/questions/386294 

88 

89BOOTSTRAP4 = { 

90 "include_jquery": False, 

91 "javascript_in_head": False, 

92 "css_url": { 

93 "href": "/static/css/bootstrap.min.css", 

94 "integrity": "sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB", 

95 "crossorigin": "anonymous", 

96 }, 

97 "javascript_url": { 

98 "url": "/static/js/bootstrap.min.js", 

99 "integrity": "", 

100 "crossorigin": "anonymous", 

101 }, 

102 "popper_url": { 

103 "url": "/static/js/popper.min.js", 

104 "integrity": "sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49", 

105 "crossorigin": "anonymous", 

106 }, 

107} 

108 

109if "EMAIL_BACKEND" in os.environ: 

110 EMAIL_BACKEND = os.environ["EMAIL_BACKEND"] # pragma: no cover 

111else: 

112 if "test" in sys.argv or "collectstatic" in sys.argv: 

113 EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend" 

114 else: 

115 try: 

116 ANYMAIL = { # pragma: no cover 

117 "MAILGUN_API_KEY": os.environ["IVATAR_MAILGUN_API_KEY"], 

118 "MAILGUN_SENDER_DOMAIN": os.environ["IVATAR_MAILGUN_SENDER_DOMAIN"], 

119 } 

120 EMAIL_BACKEND = "anymail.backends.mailgun.EmailBackend" # pragma: no cover 

121 except Exception: # pragma: nocover # pylint: disable=broad-except 

122 EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" 

123 

124SERVER_EMAIL = os.environ.get("SERVER_EMAIL", "ivatar@mg.linux-kernel.at") 

125DEFAULT_FROM_EMAIL = os.environ.get("DEFAULT_FROM_EMAIL", "ivatar@mg.linux-kernel.at") 

126 

127try: 

128 from ivatar.settings import DATABASES 

129except ImportError: # pragma: no cover 

130 DATABASES = [] # pragma: no cover 

131 

132if "default" not in DATABASES: 

133 DATABASES["default"] = { # pragma: no cover 

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

135 "NAME": os.path.join(BASE_DIR, "db.sqlite3"), 

136 } 

137 

138if "MYSQL_DATABASE" in os.environ: 

139 DATABASES["default"] = { # pragma: no cover 

140 "ENGINE": "django.db.backends.mysql", 

141 "NAME": os.environ["MYSQL_DATABASE"], 

142 "USER": os.environ["MYSQL_USER"], 

143 "PASSWORD": os.environ["MYSQL_PASSWORD"], 

144 "HOST": "mysql", 

145 } 

146 

147if "POSTGRESQL_DATABASE" in os.environ: 

148 DATABASES["default"] = { # pragma: no cover 

149 "ENGINE": "django.db.backends.postgresql", 

150 "NAME": os.environ["POSTGRESQL_DATABASE"], 

151 "USER": os.environ["POSTGRESQL_USER"], 

152 "PASSWORD": os.environ["POSTGRESQL_PASSWORD"], 

153 "HOST": "postgresql", 

154 } 

155 

156# CI/CD config has different naming 

157if "POSTGRES_DB" in os.environ: 

158 DATABASES["default"] = { # pragma: no cover 

159 "ENGINE": "django.db.backends.postgresql", 

160 "NAME": os.environ["POSTGRES_DB"], 

161 "USER": os.environ["POSTGRES_USER"], 

162 "PASSWORD": os.environ["POSTGRES_PASSWORD"], 

163 "HOST": os.environ["POSTGRES_HOST"], 

164 "TEST": { 

165 "NAME": os.environ["POSTGRES_DB"], 

166 }, 

167 } 

168 

169SESSION_SERIALIZER = "django.contrib.sessions.serializers.JSONSerializer" 

170 

171USE_X_FORWARDED_HOST = True 

172ALLOWED_EXTERNAL_OPENID_REDIRECT_DOMAINS = [ 

173 "avatars.linux-kernel.at", 

174 "localhost", 

175] 

176 

177DEFAULT_AVATAR_SIZE = 80 

178 

179LANGUAGES = ( 

180 ("de", _("Deutsch")), 

181 ("en", _("English")), 

182 ("ca", _("Català")), 

183 ("cs", _("Česky")), 

184 ("es", _("Español")), 

185 ("eu", _("Basque")), 

186 ("fr", _("Français")), 

187 ("it", _("Italiano")), 

188 ("ja", _("日本語")), 

189 ("nl", _("Nederlands")), 

190 ("pt", _("Português")), 

191 ("ru", _("Русский")), 

192 ("sq", _("Shqip")), 

193 ("tr", _("Türkçe")), 

194 ("uk", _("Українська")), 

195) 

196 

197MESSAGE_TAGS = { 

198 message_constants.DEBUG: "debug", 

199 message_constants.INFO: "info", 

200 message_constants.SUCCESS: "success", 

201 message_constants.WARNING: "warning", 

202 message_constants.ERROR: "danger", 

203} 

204 

205CACHES = { 

206 "default": { 

207 "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache", 

208 "LOCATION": [ 

209 "127.0.0.1:11211", 

210 ], 

211 }, 

212 "filesystem": { 

213 "BACKEND": "django.core.cache.backends.filebased.FileBasedCache", 

214 "LOCATION": "/var/tmp/ivatar_cache", 

215 "TIMEOUT": 900, # 15 minutes 

216 }, 

217} 

218 

219# This is 5 minutes caching for generated/resized images, 

220# so the sites don't hit ivatar so much - it's what's set in the HTTP header 

221CACHE_IMAGES_MAX_AGE = 5 * 60 

222 

223CACHE_RESPONSE = True 

224 

225# Trusted URLs for default redirection 

226TRUSTED_DEFAULT_URLS = [ 

227 {"schemes": ["https"], "host_equals": "ui-avatars.com", "path_prefix": "/api/"}, 

228 { 

229 "schemes": ["http", "https"], 

230 "host_equals": "gravatar.com", 

231 "path_prefix": "/avatar/", 

232 }, 

233 { 

234 "schemes": ["http", "https"], 

235 "host_suffix": ".gravatar.com", 

236 "path_prefix": "/avatar/", 

237 }, 

238 { 

239 "schemes": ["http", "https"], 

240 "host_equals": "www.gravatar.org", 

241 "path_prefix": "/avatar/", 

242 }, 

243 { 

244 "schemes": ["https"], 

245 "host_equals": "avatars.dicebear.com", 

246 "path_prefix": "/api/", 

247 }, 

248 { 

249 "schemes": ["https"], 

250 "host_equals": "api.dicebear.com", 

251 "path_prefix": "/", 

252 }, 

253 { 

254 "schemes": ["https"], 

255 "host_equals": "badges.fedoraproject.org", 

256 "path_prefix": "/static/img/", 

257 }, 

258 { 

259 "schemes": ["http"], 

260 "host_equals": "www.planet-libre.org", 

261 "path_prefix": "/themes/planetlibre/images/", 

262 }, 

263 {"schemes": ["https"], "host_equals": "www.azuracast.com", "path_prefix": "/img/"}, 

264 { 

265 "schemes": ["https"], 

266 "host_equals": "reps.mozilla.org", 

267 "path_prefix": "/static/base/img/remo/", 

268 }, 

269] 

270 

271# This MUST BE THE LAST! 

272if os.path.isfile(os.path.join(BASE_DIR, "config_local.py")): 

273 from config_local import * # noqa # flake8: noqa # NOQA # pragma: no cover 

274 

275 

276def map_legacy_config(trusted_url): 

277 """ 

278 For backward compability with the legacy configuration 

279 for trusting URLs. Adapts them to fit the new config. 

280 """ 

281 if isinstance(trusted_url, str): 

282 return {"url_prefix": trusted_url} 

283 

284 return trusted_url 

285 

286 

287# Backward compability for legacy behavior 

288TRUSTED_DEFAULT_URLS = list(map(map_legacy_config, TRUSTED_DEFAULT_URLS))