Skip to content

Commit da89001

Browse files
authored
WIP: add authenticati (#4)
on to onboarding
1 parent b87ee8f commit da89001

File tree

10 files changed

+124
-2
lines changed

10 files changed

+124
-2
lines changed

.env

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ DEBUG=True
44
DJANGO_SETTINGS_MODULE=api.settings
55
SECRET_KEY=secret
66

7+
# Default admin credentials (change DEFAULT_ADMIN_PASSWORD for production!)
8+
DEFAULT_ADMIN_USERNAME=admin
9+
DEFAULT_ADMIN_PASSWORD=admin
10+
DEFAULT_ADMIN_EMAIL=admin@admin.com
11+
712
# used to generate the JWT token
813
INIT_TOKEN_SECRET=supersecret
914

Dockerfile

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,20 @@ ENV PYTHONUNBUFFERED 1
1616

1717
RUN apk add --update --no-cache --virtual .tmp-build-deps \
1818
gcc libc-dev linux-headers postgresql-dev \
19-
&& apk add libffi-dev
19+
&& apk add libffi-dev netcat-openbsd
2020

2121
# install dependencies
2222
RUN pip install --upgrade pip
2323

24-
# copy whole project to your docker home directory.
24+
# copy whole project to your docker home directory.
2525
COPY . $DockerHOME
2626

2727
# run this command to install all dependencies
2828
RUN pip install -r requirements.txt
29+
30+
# copy entrypoint script and make it executable
31+
COPY entrypoint.sh /entrypoint.sh
32+
RUN chmod +x /entrypoint.sh
33+
34+
# set entrypoint
35+
ENTRYPOINT ["/entrypoint.sh"]

api/settings.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@
112112

113113
AUTH_USER_MODEL = 'app.User'
114114

115+
# Default admin user credentials
116+
DEFAULT_ADMIN_USERNAME = os.getenv('DEFAULT_ADMIN_USERNAME', 'admin')
117+
DEFAULT_ADMIN_PASSWORD = os.getenv('DEFAULT_ADMIN_PASSWORD', 'admin')
118+
DEFAULT_ADMIN_EMAIL = os.getenv('DEFAULT_ADMIN_EMAIL', 'admin@admin.com')
119+
115120
# Password validation
116121
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
117122

app/management/__init__.py

Whitespace-only changes.

app/management/commands/__init__.py

Whitespace-only changes.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import os
2+
from django.core.management.base import BaseCommand
3+
from django.contrib.auth import get_user_model
4+
5+
User = get_user_model()
6+
7+
8+
class Command(BaseCommand):
9+
help = 'Initialize default admin user (idempotent)'
10+
11+
def handle(self, *args, **options):
12+
# Get admin credentials from environment variables
13+
admin_username = os.environ.get('DEFAULT_ADMIN_USERNAME', 'admin')
14+
admin_password = os.environ.get('DEFAULT_ADMIN_PASSWORD', 'admin')
15+
admin_email = os.environ.get('DEFAULT_ADMIN_EMAIL', 'admin@admin.com')
16+
17+
# Check if admin user already exists
18+
if User.objects.filter(username=admin_username).exists():
19+
self.stdout.write(
20+
self.style.WARNING(f'Admin user "{admin_username}" already exists. Skipping creation.')
21+
)
22+
return
23+
24+
# Create the admin user
25+
try:
26+
admin_user = User.objects.create_superuser(
27+
username=admin_username,
28+
email=admin_email,
29+
password=admin_password
30+
)
31+
admin_user.is_verified = True
32+
admin_user.save()
33+
34+
self.stdout.write(
35+
self.style.SUCCESS(
36+
f'Successfully created admin user "{admin_username}" with default password. '
37+
f'Please change the password after first login.'
38+
)
39+
)
40+
except Exception as e:
41+
self.stdout.write(
42+
self.style.ERROR(f'Failed to create admin user: {str(e)}')
43+
)
44+
raise

app/models/__init__.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from .user import User
2+
from .organization import Organization
3+
from .app import App
4+
from .conference import Conference
5+
from .participant import Participant
6+
from .session import Session
7+
from .summary import Summary
8+
from .track import Track
9+
from .connection import Connection
10+
from .generic_event import GenericEvent
11+
from .issue import Issue
12+
13+
__all__ = [
14+
'User',
15+
'Organization',
16+
'App',
17+
'Conference',
18+
'Participant',
19+
'Session',
20+
'Summary',
21+
'Track',
22+
'Connection',
23+
'GenericEvent',
24+
'Issue',
25+
]
26+

app/models/user.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class User(AbstractUser, BaseModel):
1717
1818
Fields:
1919
id: ID from db, UUID
20+
organization: the organization this user belongs to, fk
2021
last_active: the last time the user was active, date
2122
notifications: notifications, dict
2223
is_verified: True if the user verified the provided email, bool
@@ -28,6 +29,14 @@ class Meta:
2829
db_table = 'users'
2930

3031
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
32+
organization = models.ForeignKey(
33+
'Organization',
34+
on_delete=models.SET_NULL,
35+
null=True,
36+
blank=True,
37+
related_name='users',
38+
help_text='The organization this user belongs to'
39+
)
3140
last_active = models.DateField(default=datetime.datetime.utcnow, null=True, blank=True)
3241
notifications = JSONField(null=True, blank=True, default=dict)
3342
is_verified = models.BooleanField(default=False)

app/views/organizations_view.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from ..utils import JSONHttpResponse, serialize, validate_string
88
from .crud_view import CrudView
99

10+
1011
class OrganizatonsView(CrudView):
1112
"""
1213
Endpoint for editing, creating and retrieving organizations.
@@ -41,6 +42,9 @@ def post(cls, request, pk=None):
4142

4243
organization.save()
4344

45+
request.user.organization = organization
46+
request.user.save()
47+
4448
return JSONHttpResponse(
4549
status=200,
4650
content=serialize(

entrypoint.sh

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/bin/sh
2+
3+
# Exit on error
4+
set -e
5+
6+
echo "Waiting for postgres..."
7+
while ! nc -z $DATABASE_HOST $DATABASE_PORT; do
8+
sleep 0.1
9+
done
10+
echo "PostgreSQL started"
11+
12+
echo "Running migrations..."
13+
python manage.py migrate --noinput
14+
15+
echo "Collecting static files..."
16+
python manage.py collectstatic --noinput
17+
18+
echo "Initializing admin user..."
19+
python manage.py init_admin
20+
21+
echo "Starting Gunicorn..."
22+
exec gunicorn api.wsgi:application --bind 0.0.0.0:8081 --log-level debug --reload

0 commit comments

Comments
 (0)