We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Migrate from CAPTCHA to Turnstile
Turnstile
* is not from *Google*.
* doesn't force users to help train Google's car AI.
* easy (?) to [migrate to](https://developers.cloudflare.com/turnstile/get-started/migrating-from-recaptcha/).
* solves the stupid issue with showing captchas so early they expire (Bc. a Turnstile token is valid for 300 seconds).

Closes #2291 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lego/settings/development.py`
Content:
```
1 import os
2 
3 import stripe
4 
5 from .base import INSTALLED_APPS, MIDDLEWARE
6 from .rest_framework import REST_FRAMEWORK
7 
8 DEBUG = True
9 DEVELOPMENT = True
10 
11 SERVER_URL = "http://127.0.0.1:8000"
12 FRONTEND_URL = "http://127.0.0.1:3000"
13 SERVER_EMAIL = "Abakus <no-reply@abakus.no>"
14 ENVIRONMENT_NAME = "development"
15 
16 SECRET_KEY = "secret"
17 
18 stripe.api_key = os.environ.get("STRIPE_TEST_KEY")
19 STRIPE_WEBHOOK_SECRET = os.environ.get("STRIPE_WEBHOOK_SECRET")
20 CAPTCHA_KEY = (
21     os.environ.get("CAPTCHA_KEY") or "6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe"
22 )
23 
24 SESSION_COOKIE_SECURE = False
25 DATABASES = {
26     "default": {
27         "ENGINE": "django.db.backends.postgresql",
28         "HOST": "127.0.0.1",
29         "NAME": "lego",
30         "USER": "lego",
31         "PASSWORD": "",
32         "PORT": "",
33     }
34 }
35 
36 CACHES = {
37     "default": {
38         "BACKEND": "django_redis.cache.RedisCache",
39         "LOCATION": "redis://127.0.0.1:6379/0",
40         "OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient"},
41     }
42 }
43 
44 EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
45 
46 INTERNAL_IPS = ["127.0.0.1"]
47 INSTALLED_APPS += ["coverage", "debug_toolbar"]
48 MIDDLEWARE += ["debug_toolbar.middleware.DebugToolbarMiddleware"]
49 DEBUG_TOOLBAR_PANELS = [
50     "debug_toolbar.panels.versions.VersionsPanel",
51     "debug_toolbar.panels.timer.TimerPanel",
52     "debug_toolbar.panels.settings.SettingsPanel",
53     "debug_toolbar.panels.headers.HeadersPanel",
54     "debug_toolbar.panels.request.RequestPanel",
55     "debug_toolbar.panels.sql.SQLPanel",
56     "debug_toolbar.panels.staticfiles.StaticFilesPanel",
57     "debug_toolbar.panels.templates.TemplatesPanel",
58     "debug_toolbar.panels.cache.CachePanel",
59     "debug_toolbar.panels.signals.SignalsPanel",
60     "debug_toolbar.panels.logging.LoggingPanel",
61     "debug_toolbar.panels.redirects.RedirectsPanel",
62 ]
63 
64 REST_FRAMEWORK["DEFAULT_RENDERER_CLASSES"] += [  # type: ignore
65     # "rest_framework.renderers.BrowsableAPIRenderer"
66     "djangorestframework_camel_case.render.CamelCaseBrowsableAPIRenderer"
67 ]
68 
69 AWS_ACCESS_KEY_ID = "lego-dev"
70 AWS_SECRET_ACCESS_KEY = "lego-dev"
71 AWS_REGION = "us-east-1"
72 AWS_S3_BUCKET = "lego"
73 AWS_ENTRYPOINT = "http://127.0.0.1:9000"
74 
75 THUMBOR_SERVER = "http://127.0.0.1:10000"
76 THUMBOR_SECURITY_KEY = "lego-dev"
77 
78 CELERY_BROKER_URL = "redis://127.0.0.1"
79 CELERY_TASK_ALWAYS_EAGER = True
80 
81 ELASTICSEARCH = "127.0.0.1"
82 SEARCH_BACKEND = os.environ.get("SEARCH_BACKEND", "postgres")
83 
84 LDAP_SERVER = "127.0.0.1:389"
85 LDAP_USER = "cn=admin,dc=abakus,dc=no"
86 LDAP_PASSWORD = "admin"
87 
88 CORS_ORIGIN_WHITELIST = list({"http://127.0.0.1:3000", "http://localhost:3000"})
89 
90 SEARCH_INDEX = "lego-search"
91
```

Path: `lego/settings/base.py`
Content:
```
1 import base64
2 import datetime
3 import json
4 import os
5 
6 import environ
7 
8 root = environ.Path(__file__) - 2
9 BASE_DIR = root()
10 
11 ALLOWED_HOSTS = ["*"]
12 SHELL_PLUS = "ipython"
13 
14 INSTALLED_APPS = [
15     "django.contrib.auth",
16     "django.contrib.contenttypes",
17     "django.contrib.sessions",
18     "django.contrib.messages",
19     "django.contrib.staticfiles",
20     "django.contrib.postgres",
21     "django_extensions",
22     "oauth2_provider",
23     "rest_framework",
24     "rest_framework_jwt",
25     "rest_framework_jwt.blacklist",  # Not used, but needed to avoid db issues.
26     "corsheaders",
27     "mptt",
28     "channels",
29     "django_filters",
30     "push_notifications",
31     "health_check",
32     "phonenumber_field",
33     "lego.utils",
34     "lego.apps.action_handlers",
35     "lego.apps.articles",
36     "lego.apps.comments",
37     "lego.apps.companies",
38     "lego.apps.contact",
39     "lego.apps.content",
40     "lego.apps.email",
41     "lego.apps.emojis",
42     "lego.apps.events",
43     "lego.apps.external_sync",
44     "lego.apps.feeds",
45     "lego.apps.files",
46     "lego.apps.flatpages",
47     "lego.apps.followers",
48     "lego.apps.frontpage",
49     "lego.apps.gallery",
50     "lego.apps.healthchecks",
51     "lego.apps.ical",
52     "lego.apps.joblistings",
53     "lego.apps.meetings",
54     "lego.apps.notifications",
55     "lego.apps.oauth",
56     "lego.apps.permissions",
57     "lego.apps.podcasts",
58     "lego.apps.polls",
59     "lego.apps.quotes",
60     "lego.apps.reactions",
61     "lego.apps.restricted",
62     "lego.apps.search",
63     "lego.apps.stats",
64     "lego.apps.surveys",
65     "lego.apps.tags",
66     "lego.apps.users",
67     "lego.apps.websockets",
68 ]
69 
70 DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
71 SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"
72 AUTH_USER_MODEL = "users.User"
73 AUTHENTICATION_BACKENDS = ("lego.apps.permissions.backends.LegoPermissionBackend",)
74 LOGIN_URL = "/authorization/login/"
75 LOGOUT_URL = "/authorization/logout/"
76 AUTH_PASSWORD_VALIDATORS = [
77     {
78         "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"
79     },
80     {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
81     {"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
82     {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
83 ]
84 
85 MIDDLEWARE = [
86     "django.middleware.security.SecurityMiddleware",
87     "django.contrib.sessions.middleware.SessionMiddleware",
88     "lego.utils.middleware.cors.CORSPatchMiddleware",
89     "corsheaders.middleware.CorsMiddleware",
90     "django.middleware.common.CommonMiddleware",
91     "django.middleware.csrf.CsrfViewMiddleware",
92     "django.contrib.auth.middleware.AuthenticationMiddleware",
93     "django.contrib.messages.middleware.MessageMiddleware",
94     "django.middleware.clickjacking.XFrameOptionsMiddleware",
95     "lego.utils.middleware.logging.LoggingMiddleware",
96 ]
97 
98 TEMPLATES = [
99     {
100         "BACKEND": "django.template.backends.django.DjangoTemplates",
101         "DIRS": [os.path.join(BASE_DIR, "templates")],
102         "APP_DIRS": True,
103         "OPTIONS": {
104             "context_processors": [
105                 "django.contrib.auth.context_processors.auth",
106                 "django.template.context_processors.debug",
107                 "django.template.context_processors.i18n",
108                 "django.template.context_processors.media",
109                 "django.template.context_processors.static",
110                 "django.template.context_processors.tz",
111                 "django.contrib.messages.context_processors.messages",
112                 "lego.utils.context_processors.site",
113             ]
114         },
115     }
116 ]
117 
118 JWT_AUTH = {
119     "JWT_RESPONSE_PAYLOAD_HANDLER": "lego.apps.jwt.handlers.response_handler",
120     # Tokens will expire after 14 days
121     "JWT_EXPIRATION_DELTA": datetime.timedelta(days=14),
122     # Allow refresh. Tokens can be refreshed for 180 days after initial login,
123     # so users must login ~twice a year
124     "JWT_ALLOW_REFRESH": True,
125     "JWT_REFRESH_EXPIRATION_DELTA": datetime.timedelta(days=180),
126 }
127 
128 OAUTH2_PROVIDER_APPLICATION_MODEL = "oauth.APIApplication"
129 OAUTH2_PROVIDER_ACCESS_TOKEN_MODEL = "oauth2_provider.AccessToken"
130 OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL = "oauth2_provider.RefreshToken"
131 OAUTH2_PROVIDER_ID_TOKEN_MODEL = "oauth2_provider.IDToken"
132 # Tokens is valid for 7 days.
133 OAUTH2_PROVIDER = {
134     "ACCESS_TOKEN_EXPIRE_SECONDS": 86400 * 7,
135     "SCOPES": {
136         "user": (
137             "Enkel brukerinfo. Dette gir lesetilgang til ditt navn, "
138             "brukernavn, profilbilde, epost, kjønn og dine medlemskap"
139         ),
140         "all": "Gir tilgang til all brukerinfo. Kan også gjøre ting som deg",
141     },
142 }
143 
144 ROOT_URLCONF = "lego.urls"
145 
146 WSGI_APPLICATION = "lego.wsgi.application"
147 
148 SEARCH_BACKEND = "postgres"
149 
150 TIME_ZONE = "UTC"
151 USE_I18N = False
152 USE_L10N = False
153 USE_TZ = True
154 
155 STATICFILES_STORAGE = "django.contrib.staticfiles.storage.StaticFilesStorage"
156 STATICFILES_FINDERS = (
157     "django.contrib.staticfiles.finders.FileSystemFinder",
158     "django.contrib.staticfiles.finders.AppDirectoriesFinder",
159 )
160 STATIC_ROOT = os.path.join(BASE_DIR, "files", "static")
161 STATIC_URL = "/static/"
162 STATICFILES_DIRS = (("assets", os.path.join(BASE_DIR, "assets")),)
163 
164 MEDIA_ROOT = os.path.join(BASE_DIR, "files", "media")
165 MEDIA_URL = "/media/"
166 
167 ASGI_APPLICATION = "lego.apps.websockets.routing.application"
168 CHANNEL_LAYERS = {
169     "default": {
170         "BACKEND": "channels_redis.core.RedisChannelLayer",
171         "CONFIG": {"hosts": ["redis://127.0.0.1:6379"]},
172     }
173 }
174 
175 LDAP_BASE_DN = "dc=abakus,dc=no"
176 
177 CAPTCHA_URL = "https://www.google.com/recaptcha/api/siteverify"
178 
179 PUSH_NOTIFICATIONS_SETTINGS = {
180     "APNS_USE_SANDBOX": False,
181     "UPDATE_ON_DUPLICATE_REG_ID": True,
182     "APNS_TOPIC": "no.abakus.abakus",
183     "GCM_ERROR_TIMEOUT": 30,
184     "FCM_ERROR_TIMEOUT": 30,
185 }
186 
187 GSUITE_DELEGATED_ACCOUNT = os.environ.get("GSUITE_DELEGATED_ACCOUNT")
188 SMTP_SSL_ENABLE = os.environ.get("SMTP_SSL_ENABLE") or False
189 SMTP_SSL_CERTIFICATE = os.environ.get("SMTP_SSL_CERTIFICATE")
190 SMTP_SSL_KEY = os.environ.get("SMTP_SSL_KEY")
191 
192 if os.environ.get("GSUITE_CREDENTIALS"):
193     GSUITE_CREDENTIALS = json.loads(
194         base64.b64decode(os.environ.get("GSUITE_CREDENTIALS")), strict=False  # type: ignore
195     )
196 else:
197     GSUITE_CREDENTIALS = None
198
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/lego/settings/base.py b/lego/settings/base.py
--- a/lego/settings/base.py
+++ b/lego/settings/base.py
@@ -174,7 +174,7 @@
 
 LDAP_BASE_DN = "dc=abakus,dc=no"
 
-CAPTCHA_URL = "https://www.google.com/recaptcha/api/siteverify"
+CAPTCHA_URL = "https://challenges.cloudflare.com/turnstile/v0/siteverify"
 
 PUSH_NOTIFICATIONS_SETTINGS = {
     "APNS_USE_SANDBOX": False,
diff --git a/lego/settings/development.py b/lego/settings/development.py
--- a/lego/settings/development.py
+++ b/lego/settings/development.py
@@ -17,9 +17,7 @@
 
 stripe.api_key = os.environ.get("STRIPE_TEST_KEY")
 STRIPE_WEBHOOK_SECRET = os.environ.get("STRIPE_WEBHOOK_SECRET")
-CAPTCHA_KEY = (
-    os.environ.get("CAPTCHA_KEY") or "6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe"
-)
+CAPTCHA_KEY = os.environ.get("CAPTCHA_KEY") or "1x0000000000000000000000000000000AA"
 
 SESSION_COOKIE_SECURE = False
 DATABASES = {

{"golden_diff": "diff --git a/lego/settings/base.py b/lego/settings/base.py\n--- a/lego/settings/base.py\n+++ b/lego/settings/base.py\n@@ -174,7 +174,7 @@\n \n LDAP_BASE_DN = \"dc=abakus,dc=no\"\n \n-CAPTCHA_URL = \"https://www.google.com/recaptcha/api/siteverify\"\n+CAPTCHA_URL = \"https://challenges.cloudflare.com/turnstile/v0/siteverify\"\n \n PUSH_NOTIFICATIONS_SETTINGS = {\n     \"APNS_USE_SANDBOX\": False,\ndiff --git a/lego/settings/development.py b/lego/settings/development.py\n--- a/lego/settings/development.py\n+++ b/lego/settings/development.py\n@@ -17,9 +17,7 @@\n \n stripe.api_key = os.environ.get(\"STRIPE_TEST_KEY\")\n STRIPE_WEBHOOK_SECRET = os.environ.get(\"STRIPE_WEBHOOK_SECRET\")\n-CAPTCHA_KEY = (\n-    os.environ.get(\"CAPTCHA_KEY\") or \"6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe\"\n-)\n+CAPTCHA_KEY = os.environ.get(\"CAPTCHA_KEY\") or \"1x0000000000000000000000000000000AA\"\n \n SESSION_COOKIE_SECURE = False\n DATABASES = {\n", "issue": "Migrate from CAPTCHA to Turnstile\nTurnstile\r\n* is not from *Google*.\r\n* doesn't force users to help train Google's car AI.\r\n* easy (?) to [migrate to](https://developers.cloudflare.com/turnstile/get-started/migrating-from-recaptcha/).\r\n* solves the stupid issue with showing captchas so early they expire (Bc. a Turnstile token is valid for 300 seconds).\r\n\r\nCloses #2291 \n", "before_files": [{"content": "import os\n\nimport stripe\n\nfrom .base import INSTALLED_APPS, MIDDLEWARE\nfrom .rest_framework import REST_FRAMEWORK\n\nDEBUG = True\nDEVELOPMENT = True\n\nSERVER_URL = \"http://127.0.0.1:8000\"\nFRONTEND_URL = \"http://127.0.0.1:3000\"\nSERVER_EMAIL = \"Abakus <no-reply@abakus.no>\"\nENVIRONMENT_NAME = \"development\"\n\nSECRET_KEY = \"secret\"\n\nstripe.api_key = os.environ.get(\"STRIPE_TEST_KEY\")\nSTRIPE_WEBHOOK_SECRET = os.environ.get(\"STRIPE_WEBHOOK_SECRET\")\nCAPTCHA_KEY = (\n    os.environ.get(\"CAPTCHA_KEY\") or \"6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe\"\n)\n\nSESSION_COOKIE_SECURE = False\nDATABASES = {\n    \"default\": {\n        \"ENGINE\": \"django.db.backends.postgresql\",\n        \"HOST\": \"127.0.0.1\",\n        \"NAME\": \"lego\",\n        \"USER\": \"lego\",\n        \"PASSWORD\": \"\",\n        \"PORT\": \"\",\n    }\n}\n\nCACHES = {\n    \"default\": {\n        \"BACKEND\": \"django_redis.cache.RedisCache\",\n        \"LOCATION\": \"redis://127.0.0.1:6379/0\",\n        \"OPTIONS\": {\"CLIENT_CLASS\": \"django_redis.client.DefaultClient\"},\n    }\n}\n\nEMAIL_BACKEND = \"django.core.mail.backends.console.EmailBackend\"\n\nINTERNAL_IPS = [\"127.0.0.1\"]\nINSTALLED_APPS += [\"coverage\", \"debug_toolbar\"]\nMIDDLEWARE += [\"debug_toolbar.middleware.DebugToolbarMiddleware\"]\nDEBUG_TOOLBAR_PANELS = [\n    \"debug_toolbar.panels.versions.VersionsPanel\",\n    \"debug_toolbar.panels.timer.TimerPanel\",\n    \"debug_toolbar.panels.settings.SettingsPanel\",\n    \"debug_toolbar.panels.headers.HeadersPanel\",\n    \"debug_toolbar.panels.request.RequestPanel\",\n    \"debug_toolbar.panels.sql.SQLPanel\",\n    \"debug_toolbar.panels.staticfiles.StaticFilesPanel\",\n    \"debug_toolbar.panels.templates.TemplatesPanel\",\n    \"debug_toolbar.panels.cache.CachePanel\",\n    \"debug_toolbar.panels.signals.SignalsPanel\",\n    \"debug_toolbar.panels.logging.LoggingPanel\",\n    \"debug_toolbar.panels.redirects.RedirectsPanel\",\n]\n\nREST_FRAMEWORK[\"DEFAULT_RENDERER_CLASSES\"] += [  # type: ignore\n    # \"rest_framework.renderers.BrowsableAPIRenderer\"\n    \"djangorestframework_camel_case.render.CamelCaseBrowsableAPIRenderer\"\n]\n\nAWS_ACCESS_KEY_ID = \"lego-dev\"\nAWS_SECRET_ACCESS_KEY = \"lego-dev\"\nAWS_REGION = \"us-east-1\"\nAWS_S3_BUCKET = \"lego\"\nAWS_ENTRYPOINT = \"http://127.0.0.1:9000\"\n\nTHUMBOR_SERVER = \"http://127.0.0.1:10000\"\nTHUMBOR_SECURITY_KEY = \"lego-dev\"\n\nCELERY_BROKER_URL = \"redis://127.0.0.1\"\nCELERY_TASK_ALWAYS_EAGER = True\n\nELASTICSEARCH = \"127.0.0.1\"\nSEARCH_BACKEND = os.environ.get(\"SEARCH_BACKEND\", \"postgres\")\n\nLDAP_SERVER = \"127.0.0.1:389\"\nLDAP_USER = \"cn=admin,dc=abakus,dc=no\"\nLDAP_PASSWORD = \"admin\"\n\nCORS_ORIGIN_WHITELIST = list({\"http://127.0.0.1:3000\", \"http://localhost:3000\"})\n\nSEARCH_INDEX = \"lego-search\"\n", "path": "lego/settings/development.py"}, {"content": "import base64\nimport datetime\nimport json\nimport os\n\nimport environ\n\nroot = environ.Path(__file__) - 2\nBASE_DIR = root()\n\nALLOWED_HOSTS = [\"*\"]\nSHELL_PLUS = \"ipython\"\n\nINSTALLED_APPS = [\n    \"django.contrib.auth\",\n    \"django.contrib.contenttypes\",\n    \"django.contrib.sessions\",\n    \"django.contrib.messages\",\n    \"django.contrib.staticfiles\",\n    \"django.contrib.postgres\",\n    \"django_extensions\",\n    \"oauth2_provider\",\n    \"rest_framework\",\n    \"rest_framework_jwt\",\n    \"rest_framework_jwt.blacklist\",  # Not used, but needed to avoid db issues.\n    \"corsheaders\",\n    \"mptt\",\n    \"channels\",\n    \"django_filters\",\n    \"push_notifications\",\n    \"health_check\",\n    \"phonenumber_field\",\n    \"lego.utils\",\n    \"lego.apps.action_handlers\",\n    \"lego.apps.articles\",\n    \"lego.apps.comments\",\n    \"lego.apps.companies\",\n    \"lego.apps.contact\",\n    \"lego.apps.content\",\n    \"lego.apps.email\",\n    \"lego.apps.emojis\",\n    \"lego.apps.events\",\n    \"lego.apps.external_sync\",\n    \"lego.apps.feeds\",\n    \"lego.apps.files\",\n    \"lego.apps.flatpages\",\n    \"lego.apps.followers\",\n    \"lego.apps.frontpage\",\n    \"lego.apps.gallery\",\n    \"lego.apps.healthchecks\",\n    \"lego.apps.ical\",\n    \"lego.apps.joblistings\",\n    \"lego.apps.meetings\",\n    \"lego.apps.notifications\",\n    \"lego.apps.oauth\",\n    \"lego.apps.permissions\",\n    \"lego.apps.podcasts\",\n    \"lego.apps.polls\",\n    \"lego.apps.quotes\",\n    \"lego.apps.reactions\",\n    \"lego.apps.restricted\",\n    \"lego.apps.search\",\n    \"lego.apps.stats\",\n    \"lego.apps.surveys\",\n    \"lego.apps.tags\",\n    \"lego.apps.users\",\n    \"lego.apps.websockets\",\n]\n\nDEFAULT_AUTO_FIELD = \"django.db.models.AutoField\"\nSESSION_ENGINE = \"django.contrib.sessions.backends.cached_db\"\nAUTH_USER_MODEL = \"users.User\"\nAUTHENTICATION_BACKENDS = (\"lego.apps.permissions.backends.LegoPermissionBackend\",)\nLOGIN_URL = \"/authorization/login/\"\nLOGOUT_URL = \"/authorization/logout/\"\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.UserAttributeSimilarityValidator\"\n    },\n    {\"NAME\": \"django.contrib.auth.password_validation.MinimumLengthValidator\"},\n    {\"NAME\": \"django.contrib.auth.password_validation.CommonPasswordValidator\"},\n    {\"NAME\": \"django.contrib.auth.password_validation.NumericPasswordValidator\"},\n]\n\nMIDDLEWARE = [\n    \"django.middleware.security.SecurityMiddleware\",\n    \"django.contrib.sessions.middleware.SessionMiddleware\",\n    \"lego.utils.middleware.cors.CORSPatchMiddleware\",\n    \"corsheaders.middleware.CorsMiddleware\",\n    \"django.middleware.common.CommonMiddleware\",\n    \"django.middleware.csrf.CsrfViewMiddleware\",\n    \"django.contrib.auth.middleware.AuthenticationMiddleware\",\n    \"django.contrib.messages.middleware.MessageMiddleware\",\n    \"django.middleware.clickjacking.XFrameOptionsMiddleware\",\n    \"lego.utils.middleware.logging.LoggingMiddleware\",\n]\n\nTEMPLATES = [\n    {\n        \"BACKEND\": \"django.template.backends.django.DjangoTemplates\",\n        \"DIRS\": [os.path.join(BASE_DIR, \"templates\")],\n        \"APP_DIRS\": True,\n        \"OPTIONS\": {\n            \"context_processors\": [\n                \"django.contrib.auth.context_processors.auth\",\n                \"django.template.context_processors.debug\",\n                \"django.template.context_processors.i18n\",\n                \"django.template.context_processors.media\",\n                \"django.template.context_processors.static\",\n                \"django.template.context_processors.tz\",\n                \"django.contrib.messages.context_processors.messages\",\n                \"lego.utils.context_processors.site\",\n            ]\n        },\n    }\n]\n\nJWT_AUTH = {\n    \"JWT_RESPONSE_PAYLOAD_HANDLER\": \"lego.apps.jwt.handlers.response_handler\",\n    # Tokens will expire after 14 days\n    \"JWT_EXPIRATION_DELTA\": datetime.timedelta(days=14),\n    # Allow refresh. Tokens can be refreshed for 180 days after initial login,\n    # so users must login ~twice a year\n    \"JWT_ALLOW_REFRESH\": True,\n    \"JWT_REFRESH_EXPIRATION_DELTA\": datetime.timedelta(days=180),\n}\n\nOAUTH2_PROVIDER_APPLICATION_MODEL = \"oauth.APIApplication\"\nOAUTH2_PROVIDER_ACCESS_TOKEN_MODEL = \"oauth2_provider.AccessToken\"\nOAUTH2_PROVIDER_REFRESH_TOKEN_MODEL = \"oauth2_provider.RefreshToken\"\nOAUTH2_PROVIDER_ID_TOKEN_MODEL = \"oauth2_provider.IDToken\"\n# Tokens is valid for 7 days.\nOAUTH2_PROVIDER = {\n    \"ACCESS_TOKEN_EXPIRE_SECONDS\": 86400 * 7,\n    \"SCOPES\": {\n        \"user\": (\n            \"Enkel brukerinfo. Dette gir lesetilgang til ditt navn, \"\n            \"brukernavn, profilbilde, epost, kj\u00f8nn og dine medlemskap\"\n        ),\n        \"all\": \"Gir tilgang til all brukerinfo. Kan ogs\u00e5 gj\u00f8re ting som deg\",\n    },\n}\n\nROOT_URLCONF = \"lego.urls\"\n\nWSGI_APPLICATION = \"lego.wsgi.application\"\n\nSEARCH_BACKEND = \"postgres\"\n\nTIME_ZONE = \"UTC\"\nUSE_I18N = False\nUSE_L10N = False\nUSE_TZ = True\n\nSTATICFILES_STORAGE = \"django.contrib.staticfiles.storage.StaticFilesStorage\"\nSTATICFILES_FINDERS = (\n    \"django.contrib.staticfiles.finders.FileSystemFinder\",\n    \"django.contrib.staticfiles.finders.AppDirectoriesFinder\",\n)\nSTATIC_ROOT = os.path.join(BASE_DIR, \"files\", \"static\")\nSTATIC_URL = \"/static/\"\nSTATICFILES_DIRS = ((\"assets\", os.path.join(BASE_DIR, \"assets\")),)\n\nMEDIA_ROOT = os.path.join(BASE_DIR, \"files\", \"media\")\nMEDIA_URL = \"/media/\"\n\nASGI_APPLICATION = \"lego.apps.websockets.routing.application\"\nCHANNEL_LAYERS = {\n    \"default\": {\n        \"BACKEND\": \"channels_redis.core.RedisChannelLayer\",\n        \"CONFIG\": {\"hosts\": [\"redis://127.0.0.1:6379\"]},\n    }\n}\n\nLDAP_BASE_DN = \"dc=abakus,dc=no\"\n\nCAPTCHA_URL = \"https://www.google.com/recaptcha/api/siteverify\"\n\nPUSH_NOTIFICATIONS_SETTINGS = {\n    \"APNS_USE_SANDBOX\": False,\n    \"UPDATE_ON_DUPLICATE_REG_ID\": True,\n    \"APNS_TOPIC\": \"no.abakus.abakus\",\n    \"GCM_ERROR_TIMEOUT\": 30,\n    \"FCM_ERROR_TIMEOUT\": 30,\n}\n\nGSUITE_DELEGATED_ACCOUNT = os.environ.get(\"GSUITE_DELEGATED_ACCOUNT\")\nSMTP_SSL_ENABLE = os.environ.get(\"SMTP_SSL_ENABLE\") or False\nSMTP_SSL_CERTIFICATE = os.environ.get(\"SMTP_SSL_CERTIFICATE\")\nSMTP_SSL_KEY = os.environ.get(\"SMTP_SSL_KEY\")\n\nif os.environ.get(\"GSUITE_CREDENTIALS\"):\n    GSUITE_CREDENTIALS = json.loads(\n        base64.b64decode(os.environ.get(\"GSUITE_CREDENTIALS\")), strict=False  # type: ignore\n    )\nelse:\n    GSUITE_CREDENTIALS = None\n", "path": "lego/settings/base.py"}], "after_files": [{"content": "import os\n\nimport stripe\n\nfrom .base import INSTALLED_APPS, MIDDLEWARE\nfrom .rest_framework import REST_FRAMEWORK\n\nDEBUG = True\nDEVELOPMENT = True\n\nSERVER_URL = \"http://127.0.0.1:8000\"\nFRONTEND_URL = \"http://127.0.0.1:3000\"\nSERVER_EMAIL = \"Abakus <no-reply@abakus.no>\"\nENVIRONMENT_NAME = \"development\"\n\nSECRET_KEY = \"secret\"\n\nstripe.api_key = os.environ.get(\"STRIPE_TEST_KEY\")\nSTRIPE_WEBHOOK_SECRET = os.environ.get(\"STRIPE_WEBHOOK_SECRET\")\nCAPTCHA_KEY = os.environ.get(\"CAPTCHA_KEY\") or \"1x0000000000000000000000000000000AA\"\n\nSESSION_COOKIE_SECURE = False\nDATABASES = {\n    \"default\": {\n        \"ENGINE\": \"django.db.backends.postgresql\",\n        \"HOST\": \"127.0.0.1\",\n        \"NAME\": \"lego\",\n        \"USER\": \"lego\",\n        \"PASSWORD\": \"\",\n        \"PORT\": \"\",\n    }\n}\n\nCACHES = {\n    \"default\": {\n        \"BACKEND\": \"django_redis.cache.RedisCache\",\n        \"LOCATION\": \"redis://127.0.0.1:6379/0\",\n        \"OPTIONS\": {\"CLIENT_CLASS\": \"django_redis.client.DefaultClient\"},\n    }\n}\n\nEMAIL_BACKEND = \"django.core.mail.backends.console.EmailBackend\"\n\nINTERNAL_IPS = [\"127.0.0.1\"]\nINSTALLED_APPS += [\"coverage\", \"debug_toolbar\"]\nMIDDLEWARE += [\"debug_toolbar.middleware.DebugToolbarMiddleware\"]\nDEBUG_TOOLBAR_PANELS = [\n    \"debug_toolbar.panels.versions.VersionsPanel\",\n    \"debug_toolbar.panels.timer.TimerPanel\",\n    \"debug_toolbar.panels.settings.SettingsPanel\",\n    \"debug_toolbar.panels.headers.HeadersPanel\",\n    \"debug_toolbar.panels.request.RequestPanel\",\n    \"debug_toolbar.panels.sql.SQLPanel\",\n    \"debug_toolbar.panels.staticfiles.StaticFilesPanel\",\n    \"debug_toolbar.panels.templates.TemplatesPanel\",\n    \"debug_toolbar.panels.cache.CachePanel\",\n    \"debug_toolbar.panels.signals.SignalsPanel\",\n    \"debug_toolbar.panels.logging.LoggingPanel\",\n    \"debug_toolbar.panels.redirects.RedirectsPanel\",\n]\n\nREST_FRAMEWORK[\"DEFAULT_RENDERER_CLASSES\"] += [  # type: ignore\n    # \"rest_framework.renderers.BrowsableAPIRenderer\"\n    \"djangorestframework_camel_case.render.CamelCaseBrowsableAPIRenderer\"\n]\n\nAWS_ACCESS_KEY_ID = \"lego-dev\"\nAWS_SECRET_ACCESS_KEY = \"lego-dev\"\nAWS_REGION = \"us-east-1\"\nAWS_S3_BUCKET = \"lego\"\nAWS_ENTRYPOINT = \"http://127.0.0.1:9000\"\n\nTHUMBOR_SERVER = \"http://127.0.0.1:10000\"\nTHUMBOR_SECURITY_KEY = \"lego-dev\"\n\nCELERY_BROKER_URL = \"redis://127.0.0.1\"\nCELERY_TASK_ALWAYS_EAGER = True\n\nELASTICSEARCH = \"127.0.0.1\"\nSEARCH_BACKEND = os.environ.get(\"SEARCH_BACKEND\", \"postgres\")\n\nLDAP_SERVER = \"127.0.0.1:389\"\nLDAP_USER = \"cn=admin,dc=abakus,dc=no\"\nLDAP_PASSWORD = \"admin\"\n\nCORS_ORIGIN_WHITELIST = list({\"http://127.0.0.1:3000\", \"http://localhost:3000\"})\n\nSEARCH_INDEX = \"lego-search\"\n", "path": "lego/settings/development.py"}, {"content": "import base64\nimport datetime\nimport json\nimport os\n\nimport environ\n\nroot = environ.Path(__file__) - 2\nBASE_DIR = root()\n\nALLOWED_HOSTS = [\"*\"]\nSHELL_PLUS = \"ipython\"\n\nINSTALLED_APPS = [\n    \"django.contrib.auth\",\n    \"django.contrib.contenttypes\",\n    \"django.contrib.sessions\",\n    \"django.contrib.messages\",\n    \"django.contrib.staticfiles\",\n    \"django.contrib.postgres\",\n    \"django_extensions\",\n    \"oauth2_provider\",\n    \"rest_framework\",\n    \"rest_framework_jwt\",\n    \"rest_framework_jwt.blacklist\",  # Not used, but needed to avoid db issues.\n    \"corsheaders\",\n    \"mptt\",\n    \"channels\",\n    \"django_filters\",\n    \"push_notifications\",\n    \"health_check\",\n    \"phonenumber_field\",\n    \"lego.utils\",\n    \"lego.apps.action_handlers\",\n    \"lego.apps.articles\",\n    \"lego.apps.comments\",\n    \"lego.apps.companies\",\n    \"lego.apps.contact\",\n    \"lego.apps.content\",\n    \"lego.apps.email\",\n    \"lego.apps.emojis\",\n    \"lego.apps.events\",\n    \"lego.apps.external_sync\",\n    \"lego.apps.feeds\",\n    \"lego.apps.files\",\n    \"lego.apps.flatpages\",\n    \"lego.apps.followers\",\n    \"lego.apps.frontpage\",\n    \"lego.apps.gallery\",\n    \"lego.apps.healthchecks\",\n    \"lego.apps.ical\",\n    \"lego.apps.joblistings\",\n    \"lego.apps.meetings\",\n    \"lego.apps.notifications\",\n    \"lego.apps.oauth\",\n    \"lego.apps.permissions\",\n    \"lego.apps.podcasts\",\n    \"lego.apps.polls\",\n    \"lego.apps.quotes\",\n    \"lego.apps.reactions\",\n    \"lego.apps.restricted\",\n    \"lego.apps.search\",\n    \"lego.apps.stats\",\n    \"lego.apps.surveys\",\n    \"lego.apps.tags\",\n    \"lego.apps.users\",\n    \"lego.apps.websockets\",\n]\n\nDEFAULT_AUTO_FIELD = \"django.db.models.AutoField\"\nSESSION_ENGINE = \"django.contrib.sessions.backends.cached_db\"\nAUTH_USER_MODEL = \"users.User\"\nAUTHENTICATION_BACKENDS = (\"lego.apps.permissions.backends.LegoPermissionBackend\",)\nLOGIN_URL = \"/authorization/login/\"\nLOGOUT_URL = \"/authorization/logout/\"\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        \"NAME\": \"django.contrib.auth.password_validation.UserAttributeSimilarityValidator\"\n    },\n    {\"NAME\": \"django.contrib.auth.password_validation.MinimumLengthValidator\"},\n    {\"NAME\": \"django.contrib.auth.password_validation.CommonPasswordValidator\"},\n    {\"NAME\": \"django.contrib.auth.password_validation.NumericPasswordValidator\"},\n]\n\nMIDDLEWARE = [\n    \"django.middleware.security.SecurityMiddleware\",\n    \"django.contrib.sessions.middleware.SessionMiddleware\",\n    \"lego.utils.middleware.cors.CORSPatchMiddleware\",\n    \"corsheaders.middleware.CorsMiddleware\",\n    \"django.middleware.common.CommonMiddleware\",\n    \"django.middleware.csrf.CsrfViewMiddleware\",\n    \"django.contrib.auth.middleware.AuthenticationMiddleware\",\n    \"django.contrib.messages.middleware.MessageMiddleware\",\n    \"django.middleware.clickjacking.XFrameOptionsMiddleware\",\n    \"lego.utils.middleware.logging.LoggingMiddleware\",\n]\n\nTEMPLATES = [\n    {\n        \"BACKEND\": \"django.template.backends.django.DjangoTemplates\",\n        \"DIRS\": [os.path.join(BASE_DIR, \"templates\")],\n        \"APP_DIRS\": True,\n        \"OPTIONS\": {\n            \"context_processors\": [\n                \"django.contrib.auth.context_processors.auth\",\n                \"django.template.context_processors.debug\",\n                \"django.template.context_processors.i18n\",\n                \"django.template.context_processors.media\",\n                \"django.template.context_processors.static\",\n                \"django.template.context_processors.tz\",\n                \"django.contrib.messages.context_processors.messages\",\n                \"lego.utils.context_processors.site\",\n            ]\n        },\n    }\n]\n\nJWT_AUTH = {\n    \"JWT_RESPONSE_PAYLOAD_HANDLER\": \"lego.apps.jwt.handlers.response_handler\",\n    # Tokens will expire after 14 days\n    \"JWT_EXPIRATION_DELTA\": datetime.timedelta(days=14),\n    # Allow refresh. Tokens can be refreshed for 180 days after initial login,\n    # so users must login ~twice a year\n    \"JWT_ALLOW_REFRESH\": True,\n    \"JWT_REFRESH_EXPIRATION_DELTA\": datetime.timedelta(days=180),\n}\n\nOAUTH2_PROVIDER_APPLICATION_MODEL = \"oauth.APIApplication\"\nOAUTH2_PROVIDER_ACCESS_TOKEN_MODEL = \"oauth2_provider.AccessToken\"\nOAUTH2_PROVIDER_REFRESH_TOKEN_MODEL = \"oauth2_provider.RefreshToken\"\nOAUTH2_PROVIDER_ID_TOKEN_MODEL = \"oauth2_provider.IDToken\"\n# Tokens is valid for 7 days.\nOAUTH2_PROVIDER = {\n    \"ACCESS_TOKEN_EXPIRE_SECONDS\": 86400 * 7,\n    \"SCOPES\": {\n        \"user\": (\n            \"Enkel brukerinfo. Dette gir lesetilgang til ditt navn, \"\n            \"brukernavn, profilbilde, epost, kj\u00f8nn og dine medlemskap\"\n        ),\n        \"all\": \"Gir tilgang til all brukerinfo. Kan ogs\u00e5 gj\u00f8re ting som deg\",\n    },\n}\n\nROOT_URLCONF = \"lego.urls\"\n\nWSGI_APPLICATION = \"lego.wsgi.application\"\n\nSEARCH_BACKEND = \"postgres\"\n\nTIME_ZONE = \"UTC\"\nUSE_I18N = False\nUSE_L10N = False\nUSE_TZ = True\n\nSTATICFILES_STORAGE = \"django.contrib.staticfiles.storage.StaticFilesStorage\"\nSTATICFILES_FINDERS = (\n    \"django.contrib.staticfiles.finders.FileSystemFinder\",\n    \"django.contrib.staticfiles.finders.AppDirectoriesFinder\",\n)\nSTATIC_ROOT = os.path.join(BASE_DIR, \"files\", \"static\")\nSTATIC_URL = \"/static/\"\nSTATICFILES_DIRS = ((\"assets\", os.path.join(BASE_DIR, \"assets\")),)\n\nMEDIA_ROOT = os.path.join(BASE_DIR, \"files\", \"media\")\nMEDIA_URL = \"/media/\"\n\nASGI_APPLICATION = \"lego.apps.websockets.routing.application\"\nCHANNEL_LAYERS = {\n    \"default\": {\n        \"BACKEND\": \"channels_redis.core.RedisChannelLayer\",\n        \"CONFIG\": {\"hosts\": [\"redis://127.0.0.1:6379\"]},\n    }\n}\n\nLDAP_BASE_DN = \"dc=abakus,dc=no\"\n\nCAPTCHA_URL = \"https://challenges.cloudflare.com/turnstile/v0/siteverify\"\n\nPUSH_NOTIFICATIONS_SETTINGS = {\n    \"APNS_USE_SANDBOX\": False,\n    \"UPDATE_ON_DUPLICATE_REG_ID\": True,\n    \"APNS_TOPIC\": \"no.abakus.abakus\",\n    \"GCM_ERROR_TIMEOUT\": 30,\n    \"FCM_ERROR_TIMEOUT\": 30,\n}\n\nGSUITE_DELEGATED_ACCOUNT = os.environ.get(\"GSUITE_DELEGATED_ACCOUNT\")\nSMTP_SSL_ENABLE = os.environ.get(\"SMTP_SSL_ENABLE\") or False\nSMTP_SSL_CERTIFICATE = os.environ.get(\"SMTP_SSL_CERTIFICATE\")\nSMTP_SSL_KEY = os.environ.get(\"SMTP_SSL_KEY\")\n\nif os.environ.get(\"GSUITE_CREDENTIALS\"):\n    GSUITE_CREDENTIALS = json.loads(\n        base64.b64decode(os.environ.get(\"GSUITE_CREDENTIALS\")), strict=False  # type: ignore\n    )\nelse:\n    GSUITE_CREDENTIALS = None\n", "path": "lego/settings/base.py"}]}