Base user profile
This commit is contained in:
parent
c04d9410e9
commit
de34f1daf9
11 changed files with 130 additions and 4 deletions
|
@ -1,6 +1,7 @@
|
|||
from pathlib import Path
|
||||
|
||||
from django.urls import reverse_lazy
|
||||
from django.contrib import messages
|
||||
|
||||
from autosecretkey import AutoSecretKey
|
||||
from reportmonster.classes.config import MonsterConfig
|
||||
|
@ -166,6 +167,8 @@ else:
|
|||
# Login System
|
||||
|
||||
LOGIN_URL = reverse_lazy("core:login")
|
||||
LOGIN_REDIRECT_URL = reverse_lazy("core:dashboard")
|
||||
LOGOUT_REDIRECT_URL = reverse_lazy("core:index")
|
||||
|
||||
# Logging
|
||||
|
||||
|
@ -182,3 +185,13 @@ LOGGING = {
|
|||
'level': 'DEBUG',
|
||||
},
|
||||
}
|
||||
|
||||
# Messages
|
||||
|
||||
MESSAGE_TAGS = {
|
||||
messages.DEBUG: 'alert-info',
|
||||
messages.INFO: 'alert-info',
|
||||
messages.SUCCESS: 'alert-success',
|
||||
messages.WARNING: 'alert-warning',
|
||||
messages.ERROR: 'alert-danger',
|
||||
}
|
|
@ -7,6 +7,8 @@ from reportmonster.classes.vessel import Vessel
|
|||
|
||||
from bcrypt import checkpw
|
||||
|
||||
from ..models.auth import Profile
|
||||
|
||||
|
||||
class ReportMonsterBackend(ModelBackend):
|
||||
def authenticate(self, request, username: str = None, password: str = None):
|
||||
|
@ -17,9 +19,18 @@ class ReportMonsterBackend(ModelBackend):
|
|||
filter(lambda x: x.name == settings.LOGIN_VESSEL, monster.vessels)
|
||||
)[0]
|
||||
|
||||
try:
|
||||
userdata = list(loginvessel.getUsers(username=username).values())[0]
|
||||
except:
|
||||
return
|
||||
|
||||
if checkpw(password.encode(), userdata["password"].encode()):
|
||||
user, _ = get_user_model().objects.get_or_create(email=username)
|
||||
user.save()
|
||||
profile, _ = Profile.objects.get_or_create(user=user)
|
||||
profile.first_name = userdata["firstname"]
|
||||
profile.last_name = userdata["lastname"]
|
||||
profile.save()
|
||||
return user
|
||||
|
||||
return
|
||||
|
|
33
core/migrations/0003_vessel_profile.py
Normal file
33
core/migrations/0003_vessel_profile.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Generated by Django 4.1.1 on 2022-09-16 15:22
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0002_alter_user_totp'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Vessel',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=64)),
|
||||
('imo', models.IntegerField(blank=True, null=True)),
|
||||
('mmsi', models.IntegerField(blank=True, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Profile',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('first_name', models.CharField(max_length=128)),
|
||||
('last_name', models.CharField(max_length=128)),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
20
core/migrations/0004_alter_profile_user.py
Normal file
20
core/migrations/0004_alter_profile_user.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Generated by Django 4.1.1 on 2022-09-16 15:22
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0003_vessel_profile'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='profile',
|
||||
name='user',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,23 @@
|
|||
# Generated by Django 4.1.1 on 2022-09-16 15:33
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0004_alter_profile_user'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='profile',
|
||||
name='first_name',
|
||||
field=models.CharField(blank=True, max_length=128, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='profile',
|
||||
name='last_name',
|
||||
field=models.CharField(blank=True, max_length=128, null=True),
|
||||
),
|
||||
]
|
|
@ -27,6 +27,17 @@ class User(AbstractBaseUser, PermissionsMixin):
|
|||
return self.email
|
||||
|
||||
|
||||
class Profile(models.Model):
|
||||
user = models.OneToOneField(User, models.CASCADE)
|
||||
first_name = models.CharField(max_length=128, null=True, blank=True)
|
||||
last_name = models.CharField(max_length=128, null=True, blank=True)
|
||||
|
||||
def get_full_name(self):
|
||||
return f"{self.first_name or ''} {self.last_name or ''}"
|
||||
|
||||
__str__ = get_full_name
|
||||
|
||||
|
||||
class OTPSession(models.Model):
|
||||
uuid = models.UUIDField(default=uuid4)
|
||||
user = models.ForeignKey(User, models.CASCADE)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from django.urls import path
|
||||
from django.contrib.auth.views import LogoutView
|
||||
|
||||
from ..views import LoginView, OTPView
|
||||
|
||||
|
@ -6,4 +7,5 @@ from ..views import LoginView, OTPView
|
|||
urlpatterns = [
|
||||
path("login/", LoginView.as_view(), name="login"),
|
||||
path("login/checkotp/", OTPView.as_view(), name="checkotp"),
|
||||
path("logout/", LogoutView.as_view(), name="logout"),
|
||||
]
|
|
@ -6,5 +6,5 @@ from ..views.frontend import DashboardView, NotImplementedView
|
|||
|
||||
urlpatterns = [
|
||||
path("dashboard/", DashboardView.as_view(), name="dashboard"),
|
||||
path("", RedirectView.as_view(url=reverse_lazy("core:dashboard"))),
|
||||
path("", RedirectView.as_view(url=reverse_lazy("core:dashboard")), name="index"),
|
||||
]
|
|
@ -8,7 +8,7 @@ from django.core.exceptions import PermissionDenied
|
|||
from django.http.response import HttpResponseRedirect
|
||||
from django.urls import reverse
|
||||
|
||||
from ..models.auth import OTPSession
|
||||
from ..models.auth import OTPSession, Profile
|
||||
from ..forms.auth import OTPForm
|
||||
|
||||
|
||||
|
@ -29,6 +29,8 @@ class LoginView(DjangoLoginView):
|
|||
def form_valid(self, form):
|
||||
if not (user := form.get_user()).totp:
|
||||
login(self.request, user)
|
||||
profile, _ = Profile.objects.get_or_create(user=user)
|
||||
profile.save()
|
||||
return HttpResponseRedirect(self.get_success_url())
|
||||
|
||||
session = OTPSession.objects.create(user=user)
|
||||
|
@ -55,4 +57,6 @@ class OTPView(DjangoLoginView):
|
|||
def form_valid(self, form):
|
||||
login(self.request, self.get_otpsession().user)
|
||||
del request.session["OTPSession"]
|
||||
profile, _ = Profile.objects.get_or_create(user=user)
|
||||
profile.save()
|
||||
return HttpResponseRedirect(self.get_success_url())
|
||||
|
|
|
@ -20,6 +20,15 @@
|
|||
<a href="/"><b>Acade</b>Mon</a>
|
||||
</div>
|
||||
|
||||
{% for message in messages %}
|
||||
<div class="alert {{ message.tags }} alert-dismissible shadow fade show" role="alert">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
{{ message | safe }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body login-card-body">
|
||||
<p class="login-box-msg">Sign in using your Sea Chefs Academy credentials</p>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<img src="{% static "core/dist/images/noavatar.jpg" %}" class="img-circle elevation-2" alt="User Image">
|
||||
</div>
|
||||
<div class="info">
|
||||
<a href="#" class="d-block">{{ user.get_username }}</a>
|
||||
<a href="#" class="d-block">{{ user.profile.get_full_name }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Reference in a new issue