Skip to content

Commit f654223

Browse files
committed
Untracked redundant files, implemented OOBE wizard
1 parent e917354 commit f654223

File tree

191 files changed

+2924
-38761
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

191 files changed

+2924
-38761
lines changed

.github/workflows/deploy.yml

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,25 @@ jobs:
1919
OWNER: '${{ github.repository_owner }}'
2020

2121
- name: Set up Docker Buildx
22-
uses: docker/setup-buildx-action@v2
22+
uses: docker/setup-buildx-action@v3
2323

2424
- name: Login to GitHub Container Registry
25-
uses: docker/login-action@v2
25+
uses: docker/login-action@v3
2626
with:
2727
registry: ghcr.io
2828
username: ${{ github.actor }}
2929
password: ${{ secrets.GITHUB_TOKEN }}
3030

31+
- name: Collect static files
32+
run: |
33+
cd backend
34+
python manage.py collectstatic --noinput
35+
3136
- name: Build and push Django image
32-
uses: docker/build-push-action@v4
37+
uses: docker/build-push-action@v6
3338
with:
34-
context: ./tibiknini
35-
file: ./tibiknini/Dockerfile
39+
context: ./backend
40+
file: ./backend/Dockerfile
3641
push: true
3742
tags: ghcr.io/${{ env.OWNER_LC }}/tibiknini:latest
3843

@@ -43,7 +48,7 @@ jobs:
4348
npm run build -- --prod
4449
4550
- name: Build and push NGINX image
46-
uses: docker/build-push-action@v4
51+
uses: docker/build-push-action@v6
4752
with:
4853
context: .
4954
file: ./nginx/Dockerfile

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Ignore Django collected static files
2+
# These are generated during deployment and should not be version controlled
3+
/backend/staticfiles/
14
dumps/
25
secrets/
36
.env.prod

backend/.env.example

Lines changed: 0 additions & 7 deletions
This file was deleted.

backend/Dockerfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ RUN pip install -r /usr/src/app/requirements.txt
1212
# copy our project code
1313
COPY . /usr/src/app/
1414

15+
# Collect static files during build time
16+
# This ensures that static files are available when the container starts,
17+
# and prevents issues with empty volumes when the container is first run
18+
RUN python manage.py collectstatic --noinput
19+
1520
# expose the port 8000
1621
EXPOSE 8000
1722

backend/api/urls.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
from django.contrib.auth import views as auth_views
22
from django.urls import include, path
3-
from rest_framework.permissions import AllowAny
43

54
from core.views import PrivacyPolicyView, TermsOfServiceView
65

7-
from .views import NavbarItemList, ReCaptchaLoginView, set_csrf_token
6+
from .views import NavbarItemList, ReCaptchaLoginView, set_csrf_token, SetupView
87

98
app_name = 'api'
109

@@ -20,4 +19,6 @@
2019
path('set-csrf-token/', set_csrf_token, name='set_csrf_token'),
2120
path('auth/login/', ReCaptchaLoginView.as_view(), name='login'),
2221
path('auth/logout/', auth_views.LogoutView.as_view(), name='logout'),
22+
23+
path('setup/', SetupView.as_view(), name='setup'),
2324
]

backend/api/views.py

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@
1010
from .serializers import NavbarItemSerializer
1111
from .utils.recaptcha import verify_recaptcha
1212

13+
import os
14+
from django.conf import settings
15+
from django.core.management import call_command
16+
from django.contrib.auth import get_user_model
17+
from django.db import transaction
18+
from users.models import Profile # Import the Profile model
19+
from users.managers import CustomUserManager # Import the custom manager
20+
21+
User = get_user_model()
1322

1423
@ensure_csrf_cookie
1524
def set_csrf_token(request):
@@ -22,7 +31,6 @@ class NavbarItemList(generics.ListAPIView):
2231
queryset = NavbarItem.objects.all()
2332
serializer_class = NavbarItemSerializer
2433

25-
2634
class ReCaptchaLoginView(APIView):
2735
def post(self, request, *args, **kwargs):
2836
username = request.data.get('username')
@@ -40,4 +48,51 @@ def post(self, request, *args, **kwargs):
4048
return JsonResponse({'detail': 'Successfully logged in.'})
4149
else:
4250
return JsonResponse({'detail': 'Invalid login credentials.'}, status=status.HTTP_400_BAD_REQUEST)
43-
51+
52+
class SetupView(APIView):
53+
def post(self, request, *args, **kwargs):
54+
db_host = request.data.get('db_host')
55+
db_port = request.data.get('db_port')
56+
db_name = request.data.get('db_name')
57+
db_user = request.data.get('db_user')
58+
db_password = request.data.get('db_password')
59+
admin_username = request.data.get('admin_username')
60+
admin_email = request.data.get('admin_email')
61+
admin_password = request.data.get('admin_password')
62+
63+
# Write database settings to .env file
64+
env_path = os.path.join(settings.BASE_DIR, '.env')
65+
with open(env_path, 'a') as f:
66+
f.write(f'DATABASE_URL=postgres://{db_user}:{db_password}@{db_host}:{db_port}/{db_name}\n')
67+
68+
try:
69+
# Run migrations
70+
call_command('migrate')
71+
72+
with transaction.atomic():
73+
# Use the custom manager to create the superuser
74+
User.objects.create_superuser(
75+
username=admin_username,
76+
email=admin_email,
77+
password=admin_password
78+
)
79+
80+
# Create setup complete flag in the media directory
81+
setup_flag_path = os.path.join(settings.MEDIA_ROOT, 'setup_complete.txt')
82+
with open(setup_flag_path, 'w') as f:
83+
f.write('Setup complete')
84+
85+
return JsonResponse({'detail': 'Setup complete'}, status=status.HTTP_200_OK)
86+
87+
except Exception as e:
88+
# If an error occurs, remove the added database settings
89+
with open(env_path, 'r') as f:
90+
lines = f.readlines()
91+
with open(env_path, 'w') as f:
92+
f.writelines(lines[:-1]) # Remove the last line
93+
94+
# Log the full error for debugging
95+
import logging
96+
logging.error(f"Error during setup: {str(e)}", exc_info=True)
97+
98+
return JsonResponse({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

backend/backend/middleware.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import os
2+
from django.http import JsonResponse
3+
from django.conf import settings
4+
5+
class SetupMiddleware:
6+
def __init__(self, get_response):
7+
self.get_response = get_response
8+
9+
def __call__(self, request):
10+
setup_flag_path = os.path.join(settings.MEDIA_ROOT, 'setup_complete.txt')
11+
if not os.path.exists(setup_flag_path):
12+
if request.path.startswith('/api/setup') or request.path.startswith('/static') or request.path.startswith('/django-static'):
13+
return self.get_response(request)
14+
return JsonResponse({'detail': 'Setup required'}, status=503)
15+
response = self.get_response(request)
16+
return response

backend/backend/settings.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ def get_secret(secret_name, default=None):
7575
]
7676

7777
MIDDLEWARE = [
78+
'backend.middleware.SetupMiddleware',
7879
'corsheaders.middleware.CorsMiddleware',
7980
'django.middleware.security.SecurityMiddleware',
8081
'django.contrib.sessions.middleware.SessionMiddleware',
@@ -154,7 +155,14 @@ def get_secret(secret_name, default=None):
154155
"http://localhost",
155156
"http://127.0.0.1",
156157
]
157-
CSRF_TRUSTED_ORIGINS = ["127.0.0.1", "localhost", f"https://*.{os.getenv('DOMAIN_NAME')}"]
158+
CSRF_TRUSTED_ORIGINS = [
159+
"http://127.0.0.1",
160+
"https://127.0.0.1",
161+
"http://localhost",
162+
"https://localhost",
163+
f"https://*.{os.getenv('DOMAIN_NAME')}"
164+
]
165+
158166
SESSION_COOKIE_HTTPONLY = True
159167
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
160168

@@ -174,7 +182,7 @@ def get_secret(secret_name, default=None):
174182
EMAIL_HOST_USER = get_secret('email_host_user')
175183
EMAIL_HOST_PASSWORD = get_secret('email_host_password')
176184

177-
RECAPTCHA_SECRET_KEY = os.getenv('RECAPTCHA_SECRET_KEY')
185+
RECAPTCHA_SECRET_KEY = get_secret('recaptcha_secret_key')
178186

179187
# Default primary key field type
180188
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

backend/media/setup_complete.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Setup complete

0 commit comments

Comments
 (0)