Base user profile

This commit is contained in:
Kumi 2022-09-16 15:40:15 +00:00
parent c04d9410e9
commit de34f1daf9
Signed by: kumi
GPG key ID: ECBCC9082395383F
11 changed files with 130 additions and 4 deletions

View file

@ -1,6 +1,7 @@
from pathlib import Path from pathlib import Path
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.contrib import messages
from autosecretkey import AutoSecretKey from autosecretkey import AutoSecretKey
from reportmonster.classes.config import MonsterConfig from reportmonster.classes.config import MonsterConfig
@ -166,6 +167,8 @@ else:
# Login System # Login System
LOGIN_URL = reverse_lazy("core:login") LOGIN_URL = reverse_lazy("core:login")
LOGIN_REDIRECT_URL = reverse_lazy("core:dashboard")
LOGOUT_REDIRECT_URL = reverse_lazy("core:index")
# Logging # Logging
@ -182,3 +185,13 @@ LOGGING = {
'level': 'DEBUG', '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',
}

View file

@ -7,6 +7,8 @@ from reportmonster.classes.vessel import Vessel
from bcrypt import checkpw from bcrypt import checkpw
from ..models.auth import Profile
class ReportMonsterBackend(ModelBackend): class ReportMonsterBackend(ModelBackend):
def authenticate(self, request, username: str = None, password: str = None): 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) filter(lambda x: x.name == settings.LOGIN_VESSEL, monster.vessels)
)[0] )[0]
try:
userdata = list(loginvessel.getUsers(username=username).values())[0] userdata = list(loginvessel.getUsers(username=username).values())[0]
except:
return
if checkpw(password.encode(), userdata["password"].encode()): if checkpw(password.encode(), userdata["password"].encode()):
user, _ = get_user_model().objects.get_or_create(email=username) user, _ = get_user_model().objects.get_or_create(email=username)
user.save() 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 user
return

View 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)),
],
),
]

View 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),
),
]

View file

@ -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),
),
]

View file

@ -27,6 +27,17 @@ class User(AbstractBaseUser, PermissionsMixin):
return self.email 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): class OTPSession(models.Model):
uuid = models.UUIDField(default=uuid4) uuid = models.UUIDField(default=uuid4)
user = models.ForeignKey(User, models.CASCADE) user = models.ForeignKey(User, models.CASCADE)

View file

@ -1,4 +1,5 @@
from django.urls import path from django.urls import path
from django.contrib.auth.views import LogoutView
from ..views import LoginView, OTPView from ..views import LoginView, OTPView
@ -6,4 +7,5 @@ from ..views import LoginView, OTPView
urlpatterns = [ urlpatterns = [
path("login/", LoginView.as_view(), name="login"), path("login/", LoginView.as_view(), name="login"),
path("login/checkotp/", OTPView.as_view(), name="checkotp"), path("login/checkotp/", OTPView.as_view(), name="checkotp"),
path("logout/", LogoutView.as_view(), name="logout"),
] ]

View file

@ -6,5 +6,5 @@ from ..views.frontend import DashboardView, NotImplementedView
urlpatterns = [ urlpatterns = [
path("dashboard/", DashboardView.as_view(), name="dashboard"), 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"),
] ]

View file

@ -8,7 +8,7 @@ from django.core.exceptions import PermissionDenied
from django.http.response import HttpResponseRedirect from django.http.response import HttpResponseRedirect
from django.urls import reverse from django.urls import reverse
from ..models.auth import OTPSession from ..models.auth import OTPSession, Profile
from ..forms.auth import OTPForm from ..forms.auth import OTPForm
@ -29,6 +29,8 @@ class LoginView(DjangoLoginView):
def form_valid(self, form): def form_valid(self, form):
if not (user := form.get_user()).totp: if not (user := form.get_user()).totp:
login(self.request, user) login(self.request, user)
profile, _ = Profile.objects.get_or_create(user=user)
profile.save()
return HttpResponseRedirect(self.get_success_url()) return HttpResponseRedirect(self.get_success_url())
session = OTPSession.objects.create(user=user) session = OTPSession.objects.create(user=user)
@ -55,4 +57,6 @@ class OTPView(DjangoLoginView):
def form_valid(self, form): def form_valid(self, form):
login(self.request, self.get_otpsession().user) login(self.request, self.get_otpsession().user)
del request.session["OTPSession"] del request.session["OTPSession"]
profile, _ = Profile.objects.get_or_create(user=user)
profile.save()
return HttpResponseRedirect(self.get_success_url()) return HttpResponseRedirect(self.get_success_url())

View file

@ -20,6 +20,15 @@
<a href="/"><b>Acade</b>Mon</a> <a href="/"><b>Acade</b>Mon</a>
</div> </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">&times;</span>
</button>
{{ message | safe }}
</div>
{% endfor %}
<div class="card"> <div class="card">
<div class="card-body login-card-body"> <div class="card-body login-card-body">
<p class="login-box-msg">Sign in using your Sea Chefs Academy credentials</p> <p class="login-box-msg">Sign in using your Sea Chefs Academy credentials</p>

View file

@ -15,7 +15,7 @@
<img src="{% static "core/dist/images/noavatar.jpg" %}" class="img-circle elevation-2" alt="User Image"> <img src="{% static "core/dist/images/noavatar.jpg" %}" class="img-circle elevation-2" alt="User Image">
</div> </div>
<div class="info"> <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>
</div> </div>