Merge pull request 'feature/profile' (#66) from feature/profile into main

Reviewed-on: https://gitea.pangea.org/trustchain-oc1-orchestral/IdHub/pulls/66
This commit is contained in:
cayop 2023-10-18 09:41:15 +00:00
commit d9352a1f9f
64 changed files with 1442 additions and 216 deletions

25
idhub/admin/forms.py Normal file
View File

@ -0,0 +1,25 @@
from django import forms
from django.contrib.auth.models import User
class ProfileForm(forms.ModelForm):
MANDATORY_FIELDS = ['first_name', 'last_name', 'email', 'username']
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')
class MembershipForm(forms.ModelForm):
MANDATORY_FIELDS = ['type']
class RolForm(forms.ModelForm):
MANDATORY_FIELDS = ['name']
class ServiceForm(forms.ModelForm):
MANDATORY_FIELDS = ['domain', 'rol']
class UserRolForm(forms.ModelForm):
MANDATORY_FIELDS = ['service']

View File

@ -1,13 +1,25 @@
import logging
from django.utils.translation import gettext_lazy as _
from django.views.generic.base import TemplateView
from django.views.generic.edit import UpdateView, CreateView
from django.contrib.auth.models import User
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse_lazy
from django.contrib import messages
from idhub.models import Membership, Rol, Service, UserRol
from idhub.mixins import AdminView
from idhub.admin.forms import (
ProfileForm,
MembershipForm,
RolForm,
ServiceForm,
UserRolForm
)
class AdminDashboardView(AdminView):
template_name = "idhub/admin_dashboard.html"
class AdminDashboardView(AdminView, TemplateView):
template_name = "idhub/admin/dashboard.html"
title = _('Dashboard')
subtitle = _('Success')
icon = 'bi bi-bell'
@ -18,114 +30,424 @@ class People(AdminView):
section = "People"
class AccessControl(AdminView):
class AccessControl(AdminView, TemplateView):
title = _("Access Control Management")
section = "AccessControl"
class Credentials(AdminView):
class Credentials(AdminView, TemplateView):
title = _("Credentials Management")
section = "Credentials"
class Schemes(AdminView):
class Schemes(AdminView, TemplateView):
title = _("Schemes Management")
section = "Schemes"
class ImportExport(AdminView):
class ImportExport(AdminView, TemplateView):
title = _("Massive Data Management")
section = "ImportExport"
class AdminPeopleView(People):
template_name = "idhub/admin_people.html"
class AdminPeopleListView(People, TemplateView):
template_name = "idhub/admin/people.html"
subtitle = _('People list')
icon = 'bi bi-person'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({
'users': User.objects.filter(),
})
return context
class AdminPeopleRegisterView(People):
template_name = "idhub/admin_people_register.html"
class AdminPeopleView(People, TemplateView):
template_name = "idhub/admin/user.html"
subtitle = _('User Profile')
icon = 'bi bi-person'
model = User
def get(self, request, *args, **kwargs):
self.pk = kwargs['pk']
self.object = get_object_or_404(self.model, pk=self.pk)
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({
'object': self.object,
})
return context
class AdminPeopleActivateView(AdminPeopleView):
def get(self, request, *args, **kwargs):
self.pk = kwargs['pk']
self.object = get_object_or_404(self.model, pk=self.pk)
if self.object == self.request.user:
messages.error(self.request, _('Is not possible deactivate your account!'))
return redirect('idhub:admin_people', self.object.id)
if self.object.is_active:
self.object.is_active = False
else:
self.object.is_active = True
self.object.save()
return redirect('idhub:admin_people', self.object.id)
class AdminPeopleDeleteView(AdminPeopleView):
def get(self, request, *args, **kwargs):
self.pk = kwargs['pk']
self.object = get_object_or_404(self.model, pk=self.pk)
if self.object != self.request.user:
self.object.delete()
else:
messages.error(self.request, _('Is not possible delete your account!'))
return redirect('idhub:admin_people_list')
class AdminPeopleEditView(AdminPeopleView, UpdateView):
template_name = "idhub/admin/user_edit.html"
from_class = ProfileForm
fields = ('first_name', 'last_name', 'email', 'username')
success_url = reverse_lazy('idhub:admin_people_list')
class AdminPeopleRegisterView(People, CreateView):
template_name = "idhub/admin/people_register.html"
subtitle = _('People Register')
icon = 'bi bi-person'
model = User
from_class = ProfileForm
fields = ('first_name', 'last_name', 'email', 'username')
success_url = reverse_lazy('idhub:admin_people_list')
def get_success_url(self):
self.success_url = reverse_lazy(
'idhub:admin_people_membership_new',
kwargs={"pk": self.object.id}
)
return self.success_url
class AdminPeopleMembershipRegisterView(People, CreateView):
template_name = "idhub/admin/people_membership_register.html"
subtitle = _('People add membership')
icon = 'bi bi-person'
model = Membership
from_class = MembershipForm
fields = ('type', 'start_date', 'end_date')
success_url = reverse_lazy('idhub:admin_people_list')
def get(self, request, *args, **kwargs):
self.pk = kwargs['pk']
self.user = get_object_or_404(User, pk=self.pk)
return super().get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.pk = kwargs['pk']
self.user = get_object_or_404(User, pk=self.pk)
return super().post(request, *args, **kwargs)
def get_form(self):
form = super().get_form()
form.fields['start_date'].widget.input_type = 'date'
form.fields['end_date'].widget.input_type = 'date'
return form
def get_form_kwargs(self):
self.object = self.model(user=self.user)
kwargs = super().get_form_kwargs()
return kwargs
def get_success_url(self):
self.success_url = reverse_lazy(
'idhub:admin_people_rol_new',
kwargs={"pk": self.user.id}
)
return self.success_url
class AdminPeopleMembershipEditView(People, CreateView):
template_name = "idhub/admin/people_membership_register.html"
subtitle = _('People add membership')
icon = 'bi bi-person'
model = Membership
from_class = MembershipForm
fields = ('type', 'start_date', 'end_date')
success_url = reverse_lazy('idhub:admin_people_list')
def get_form(self):
form = super().get_form()
form.fields['start_date'].widget.input_type = 'date'
form.fields['end_date'].widget.input_type = 'date'
return form
def get_form_kwargs(self):
pk = self.kwargs.get('pk')
if pk:
self.object = get_object_or_404(self.model, pk=pk)
kwargs = super().get_form_kwargs()
return kwargs
class AdminPeopleMembershipDeleteView(AdminPeopleView):
model = Membership
def get(self, request, *args, **kwargs):
self.pk = kwargs['pk']
self.object = get_object_or_404(self.model, pk=self.pk)
if self.object != self.request.user:
user = self.object.user
self.object.delete()
else:
messages.error(self.request, _('Is not possible delete your account!'))
return redirect('idhub:admin_people_edit', user.id)
class AdminPeopleRolRegisterView(People, CreateView):
template_name = "idhub/admin/people_rol_register.html"
subtitle = _('Add Rol to User')
icon = 'bi bi-person'
model = UserRol
from_class = UserRolForm
fields = ('service',)
def get(self, request, *args, **kwargs):
self.pk = kwargs['pk']
self.user = get_object_or_404(User, pk=self.pk)
return super().get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
self.pk = kwargs['pk']
self.user = get_object_or_404(User, pk=self.pk)
return super().post(request, *args, **kwargs)
def get_form_kwargs(self):
self.object = self.model(user=self.user)
kwargs = super().get_form_kwargs()
return kwargs
def get_success_url(self):
self.success_url = reverse_lazy(
'idhub:admin_people_edit',
kwargs={"pk": self.user.id}
)
return self.success_url
class AdminPeopleRolEditView(People, CreateView):
template_name = "idhub/admin/people_rol_register.html"
subtitle = _('Edit Rol to User')
icon = 'bi bi-person'
model = UserRol
from_class = UserRolForm
fields = ('service',)
def get_form_kwargs(self):
pk = self.kwargs.get('pk')
if pk:
self.object = get_object_or_404(self.model, pk=pk)
kwargs = super().get_form_kwargs()
return kwargs
def get_success_url(self):
self.success_url = reverse_lazy(
'idhub:admin_people_edit',
kwargs={"pk": self.object.user.id}
)
return self.success_url
class AdminPeopleRolDeleteView(AdminPeopleView):
model = UserRol
def get(self, request, *args, **kwargs):
self.pk = kwargs['pk']
self.object = get_object_or_404(self.model, pk=self.pk)
user = self.object.user
self.object.delete()
return redirect('idhub:admin_people_edit', user.id)
class AdminRolesView(AccessControl):
template_name = "idhub/admin_roles.html"
template_name = "idhub/admin/roles.html"
subtitle = _('Roles Management')
icon = ''
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({
'roles': Rol.objects,
})
return context
class AdminRolRegisterView(AccessControl, CreateView):
template_name = "idhub/admin/rol_register.html"
subtitle = _('Add Rol')
icon = ''
model = Rol
from_class = RolForm
fields = ('name',)
success_url = reverse_lazy('idhub:admin_roles')
object = None
class AdminRolEditView(AccessControl, CreateView):
template_name = "idhub/admin/rol_register.html"
subtitle = _('Edit Rol')
icon = ''
model = Rol
from_class = RolForm
fields = ('name',)
success_url = reverse_lazy('idhub:admin_roles')
def get_form_kwargs(self):
pk = self.kwargs.get('pk')
if pk:
self.object = get_object_or_404(self.model, pk=pk)
kwargs = super().get_form_kwargs()
return kwargs
class AdminRolDeleteView(AccessControl):
model = Rol
def get(self, request, *args, **kwargs):
self.pk = kwargs['pk']
self.object = get_object_or_404(self.model, pk=self.pk)
self.object.delete()
return redirect('idhub:admin_roles')
class AdminServicesView(AccessControl):
template_name = "idhub/admin_services.html"
template_name = "idhub/admin/services.html"
subtitle = _('Service Management')
icon = ''
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({
'services': Service.objects,
})
return context
class AdminServiceRegisterView(AccessControl, CreateView):
template_name = "idhub/admin/service_register.html"
subtitle = _('Add Service')
icon = ''
model = Service
from_class = ServiceForm
fields = ('domain', 'description', 'rol')
success_url = reverse_lazy('idhub:admin_services')
object = None
class AdminServiceEditView(AccessControl, CreateView):
template_name = "idhub/admin/service_register.html"
subtitle = _('Edit Service')
icon = ''
model = Service
from_class = ServiceForm
fields = ('domain', 'description', 'rol')
success_url = reverse_lazy('idhub:admin_services')
def get_form_kwargs(self):
pk = self.kwargs.get('pk')
if pk:
self.object = get_object_or_404(self.model, pk=pk)
kwargs = super().get_form_kwargs()
return kwargs
class AdminServiceDeleteView(AccessControl):
model = Service
def get(self, request, *args, **kwargs):
self.pk = kwargs['pk']
self.object = get_object_or_404(self.model, pk=self.pk)
self.object.delete()
return redirect('idhub:admin_services')
class AdminCredentialsView(Credentials):
template_name = "idhub/admin_credentials.html"
template_name = "idhub/admin/credentials.html"
subtitle = _('Credentials list')
icon = ''
class AdminIssueCredentialsView(Credentials):
template_name = "idhub/admin_issue_credentials.html"
template_name = "idhub/admin/issue_credentials.html"
subtitle = _('Issuance of Credentials')
icon = ''
class AdminRevokeCredentialsView(Credentials):
template_name = "idhub/admin_revoke_credentials.html"
template_name = "idhub/admin/revoke_credentials.html"
subtitle = _('Revoke Credentials')
icon = ''
class AdminWalletIdentitiesView(Credentials):
template_name = "idhub/admin_wallet_identities.html"
template_name = "idhub/admin/wallet_identities.html"
subtitle = _('Organization Identities (DID)')
icon = 'bi bi-patch-check-fill'
wallet = True
class AdminWalletCredentialsView(Credentials):
template_name = "idhub/admin_wallet_credentials.html"
template_name = "idhub/admin/wallet_credentials.html"
subtitle = _('Credentials')
icon = 'bi bi-patch-check-fill'
wallet = True
class AdminWalletConfigIssuesView(Credentials):
template_name = "idhub/admin_wallet_issues.html"
template_name = "idhub/admin/wallet_issues.html"
subtitle = _('Configure Issues')
icon = 'bi bi-patch-check-fill'
wallet = True
class AdminSchemesView(Schemes):
template_name = "idhub/admin_schemes.html"
template_name = "idhub/admin/schemes.html"
subtitle = _('Schemes List')
icon = ''
class AdminSchemesImportView(Schemes):
template_name = "idhub/admin_schemes_import.html"
template_name = "idhub/admin/schemes_import.html"
subtitle = _('Import Schemes')
icon = ''
class AdminSchemesExportView(Schemes):
template_name = "idhub/admin_schemes_export.html"
template_name = "idhub/admin/schemes_export.html"
subtitle = _('Export Schemes')
icon = ''
class AdminImportView(ImportExport):
template_name = "idhub/admin_import.html"
template_name = "idhub/admin/import.html"
subtitle = _('Import')
icon = ''
class AdminExportView(ImportExport):
template_name = "idhub/admin_export.html"
template_name = "idhub/admin/export.html"
subtitle = _('Export')
icon = ''

View File

@ -1,4 +1,4 @@
# Generated by Django 4.2.5 on 2023-10-03 15:28
# Generated by Django 4.2.5 on 2023-10-16 09:41
from django.conf import settings
from django.db import migrations, models
@ -6,7 +6,6 @@ import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
@ -15,42 +14,118 @@ class Migration(migrations.Migration):
operations = [
migrations.CreateModel(
name='DID',
name="VCTemplate",
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('did_string', models.CharField(max_length=250)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Event',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('timestamp', models.DateTimeField()),
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("wkit_template_id", models.CharField(max_length=250)),
("data", models.TextField()),
],
),
migrations.CreateModel(
name='VerifiableCredential',
name="VerifiableCredential",
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('id_string', models.CharField(max_length=250)),
('data', models.TextField()),
('verified', models.BooleanField()),
('created_on', models.DateTimeField()),
('did_issuer', models.CharField(max_length=250)),
('did_subject', models.CharField(max_length=250)),
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("id_string", models.CharField(max_length=250)),
("verified", models.BooleanField()),
("created_on", models.DateTimeField()),
("did_issuer", models.CharField(max_length=250)),
("did_subject", models.CharField(max_length=250)),
("data", models.TextField()),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="vcredentials",
to=settings.AUTH_USER_MODEL,
),
),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='AppUser',
name="Membership",
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('django_user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"type",
models.PositiveSmallIntegerField(
choices=[(1, "Beneficiary"), (2, "Employee"), (3, "Partner")],
verbose_name="Type of membership",
),
),
(
"start_date",
models.DateField(
blank=True,
help_text="What date did the membership start?",
null=True,
verbose_name="Start date",
),
),
(
"end_date",
models.DateField(
blank=True,
help_text="What date did the membership end?",
null=True,
verbose_name="End date",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="memberships",
to=settings.AUTH_USER_MODEL,
),
),
],
),
migrations.CreateModel(
name="DID",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("did_string", models.CharField(max_length=250)),
("label", models.CharField(max_length=50)),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="dids",
to=settings.AUTH_USER_MODEL,
),
),
],
),
]

View File

@ -0,0 +1,27 @@
# Generated by Django 4.2.5 on 2023-10-17 11:28
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("idhub", "0001_initial"),
]
operations = [
migrations.CreateModel(
name="Rol",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("name", models.CharField(max_length=250)),
],
),
]

View File

@ -0,0 +1,37 @@
# Generated by Django 4.2.5 on 2023-10-17 13:29
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("idhub", "0002_rol"),
]
operations = [
migrations.CreateModel(
name="Service",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("domain", models.CharField(max_length=250)),
("description", models.CharField(max_length=250)),
(
"rol",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="services",
to="idhub.rol",
),
),
],
),
]

View File

@ -0,0 +1,45 @@
# Generated by Django 4.2.5 on 2023-10-17 14:24
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("idhub", "0003_service"),
]
operations = [
migrations.CreateModel(
name="UserRol",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"service",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="users",
to="idhub.service",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="roles",
to=settings.AUTH_USER_MODEL,
),
),
],
),
]

View File

@ -2,11 +2,10 @@ from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth import views as auth_views
from django.urls import reverse_lazy, resolve
from django.utils.translation import gettext_lazy as _
from django.views.generic.base import TemplateView
from django.shortcuts import redirect
class UserView(LoginRequiredMixin, TemplateView):
class UserView(LoginRequiredMixin):
login_url = "/login/"
wallet = False
@ -26,9 +25,9 @@ class UserView(LoginRequiredMixin, TemplateView):
class AdminView(UserView):
def get(self, request):
def get(self, request, *args, **kwargs):
if not request.user.is_superuser:
url = reverse_lazy('idhub:user_dashboard')
return redirect(url)
return super().get(request)
return super().get(request, *args, **kwargs)

View File

@ -1,27 +1,32 @@
from django.db import models
from django.contrib.auth.models import User as DjangoUser
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import User
class AppUser(models.Model):
# class AppUser(models.Model):
# Ya incluye "first_name", "last_name", "email", y "date_joined" heredando de la clase User de django.
# Falta ver que más información hay que añadir a nuestros usuarios, como los roles etc.
django_user = models.OneToOneField(DjangoUser, on_delete=models.CASCADE)
# django_user = models.OneToOneField(DjangoUser, on_delete=models.CASCADE)
# Extra data, segun entidad/organizacion
pass
# pass
class Event(models.Model):
# class Event(models.Model):
# Para los "audit logs" que se requieren en las pantallas.
timestamp = models.DateTimeField()
# timestamp = models.DateTimeField()
# Los eventos no tienen relación con otros objetos a nivel de BBDD.
event_data = models.CharField(max_length=250)
# event_data = models.CharField(max_length=250)
class DID(models.Model):
did_string = models.CharField(max_length=250)
label = models.CharField(max_length=50)
owner = models.ForeignKey(AppUser, on_delete=models.CASCADE)
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='dids',
)
# kind = "KEY|WEB"
@ -31,7 +36,11 @@ class VerifiableCredential(models.Model):
created_on = models.DateTimeField()
did_issuer = models.CharField(max_length=250)
did_subject = models.CharField(max_length=250)
owner = models.ForeignKey(AppUser, on_delete=models.CASCADE)
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='vcredentials',
)
data = models.TextField()
@ -40,3 +49,67 @@ class VCTemplate(models.Model):
data = models.TextField()
class Membership(models.Model):
"""
This model represent the relation of this user with the ecosystem.
"""
class Types(models.IntegerChoices):
BENEFICIARY = 1, _('Beneficiary')
EMPLOYEE = 2, _('Employee')
PARTNER = 3, _('Partner')
type = models.PositiveSmallIntegerField(_('Type of membership'), choices=Types.choices)
start_date = models.DateField(
_('Start date'),
help_text=_('What date did the membership start?'),
blank=True,
null=True
)
end_date = models.DateField(
_('End date'),
help_text=_('What date did the membership end?'),
blank=True,
null=True
)
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='memberships',
)
def get_type(self):
return dict(self.Types.choices).get(self.type)
class Rol(models.Model):
name = models.CharField(max_length=250)
def __str__(self):
return self.name
class Service(models.Model):
domain = models.CharField(max_length=250)
description = models.CharField(max_length=250)
rol = models.ForeignKey(
Rol,
on_delete=models.CASCADE,
related_name='services',
)
def __str__(self):
return "{} -> {}".format(self.domain, self.rol.name)
class UserRol(models.Model):
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='roles',
)
service = models.ForeignKey(
Service,
on_delete=models.CASCADE,
related_name='users',
)

View File

@ -165,3 +165,7 @@ h3 {
.btn-yellow {
background-color: #efe3b4;
}
.btn-orange {
background-color: #f5b587;
}

7
idhub/static/js/bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,53 +0,0 @@
/* globals Chart:false, feather:false */
(function () {
'use strict'
feather.replace({ 'aria-hidden': 'true' })
// Graphs
var ctx = document.getElementById('myChart')
// eslint-disable-next-line no-unused-vars
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: [
'Sunday',
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday',
'Saturday'
],
datasets: [{
data: [
15339,
21345,
18483,
24003,
23489,
24092,
12034
],
lineTension: 0,
backgroundColor: 'transparent',
borderColor: '#007bff',
borderWidth: 4,
pointBackgroundColor: '#007bff'
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: false
}
}]
},
legend: {
display: false
}
}
})
})()

File diff suppressed because one or more lines are too long

6
idhub/static/js/popper.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -2,4 +2,8 @@
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% endblock %}

View File

@ -2,6 +2,10 @@
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>

View File

@ -2,4 +2,8 @@
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% endblock %}

View File

@ -2,4 +2,8 @@
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% endblock %}

View File

@ -2,4 +2,8 @@
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% endblock %}

View File

@ -0,0 +1,43 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th scope="col"><button type="button" class="btn btn-green-admin border border-dark">{% trans 'Last name' %}</button></th>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'First name' %}</button></th>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">Username</button></th>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Membership' %}</button></th>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Role' %}</button></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.last_name }}</td>
<td>{{ user.first_name }}</td>
<td>{{ user.username }}</td>
<td>
{% for m in user.memberships.all %}
{{ m.get_type }}
{% endfor %}
</td>
<td>
{% for r in user.roles.all %}
{{ r.service.rol.name }}
{% endfor %}
</td>
<td><a type="button" class="btn btn-green-admin rounded-pill" href="{% url 'idhub:admin_people' user.id %}">{% trans 'View' %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}

View File

@ -0,0 +1,34 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% load django_bootstrap5 %}
<form role="form" method="post">
{% csrf_token %}
{% if form.errors %}
<div class="alert alert-danger alert-icon alert-icon-border alert-dismissible" role="alert">
<div class="icon"><span class="mdi mdi-close-circle-o"></span></div>
<div class="message">
{% for field, error in form.errors.items %}
{{ error }}<br />
{% endfor %}
<button class="btn-close" type="button" data-dismiss="alert" aria-label="Close"></button>
</div>
</div>
{% endif %}
<div class="row">
<div class="col-sm-4">
{% bootstrap_form form %}
</div>
</div>
<div class="form-actions-no-box">
<a class="btn btn-grey" href="{% url 'idhub:admin_people_edit' form.instance.user.id %}">{% translate "Cancel" %}</a>
<input class="btn btn-green-admin" type="submit" name="submit" value="{% translate 'Save' %}" />
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,30 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% load django_bootstrap5 %}
<form role="form" method="post">
{% csrf_token %}
{% if form.errors %}
<div class="alert alert-danger alert-icon alert-icon-border alert-dismissible" role="alert">
<div class="icon"><span class="mdi mdi-close-circle-o"></span></div>
<div class="message">
{% for field, error in form.errors.items %}
{{ error }}<br />
{% endfor %}
<button class="btn-close" type="button" data-dismiss="alert" aria-label="Close"></button>
</div>
</div>
{% endif %}
{% bootstrap_form form %}
<div class="form-actions-no-box">
<a class="btn btn-grey" href="{% url 'idhub:admin_people_list' %}">{% translate "Cancel" %}</a>
<input class="btn btn-green-admin" type="submit" name="submit" value="{% translate 'Save' %}" />
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,34 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% load django_bootstrap5 %}
<form role="form" method="post">
{% csrf_token %}
{% if form.errors %}
<div class="alert alert-danger alert-icon alert-icon-border alert-dismissible" role="alert">
<div class="icon"><span class="mdi mdi-close-circle-o"></span></div>
<div class="message">
{% for field, error in form.errors.items %}
{{ error }}<br />
{% endfor %}
<button class="btn-close" type="button" data-dismiss="alert" aria-label="Close"></button>
</div>
</div>
{% endif %}
<div class="row">
<div class="col-sm-4">
{% bootstrap_form form %}
</div>
</div>
<div class="form-actions-no-box">
<a class="btn btn-grey" href="{% url 'idhub:admin_people_edit' form.instance.user.id %}">{% translate "Cancel" %}</a>
<input class="btn btn-green-admin" type="submit" name="submit" value="{% translate 'Save' %}" />
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% endblock %}

View File

@ -0,0 +1,34 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% load django_bootstrap5 %}
<form role="form" method="post">
{% csrf_token %}
{% if form.errors %}
<div class="alert alert-danger alert-icon alert-icon-border alert-dismissible" role="alert">
<div class="icon"><span class="mdi mdi-close-circle-o"></span></div>
<div class="message">
{% for field, error in form.errors.items %}
{{ error }}<br />
{% endfor %}
<button class="btn-close" type="button" data-dismiss="alert" aria-label="Close"></button>
</div>
</div>
{% endif %}
<div class="row">
<div class="col-sm-4">
{% bootstrap_form form %}
</div>
</div>
<div class="form-actions-no-box">
<a class="btn btn-grey" href="{% url 'idhub:admin_roles' %}">{% translate "Cancel" %}</a>
<input class="btn btn-green-admin" type="submit" name="submit" value="{% translate 'Save' %}" />
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,36 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
<div class="row mt-5">
<div class="col">
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Rol' %}</button></th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{% for rol in roles.all %}
<tr>
<td>{{ rol.name }}</td>
<td><a href="{% url 'idhub:admin_rol_edit' rol.id %}" title="{% trans 'Edit' %}"><i class="bi bi-pencil-square"></i></a></td>
<td><a href="{% url 'idhub:admin_rol_del' rol.id %}" title="{% trans 'Delete' %}"><i class="bi bi-trash"></i></a></td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="form-actions-no-box">
<a class="btn btn-green-admin" href="{% url 'idhub:admin_rol_new' %}">{% translate "Add Rol" %} <i class="bi bi-plus"></i></a>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% endblock %}

View File

@ -0,0 +1,34 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% load django_bootstrap5 %}
<form role="form" method="post">
{% csrf_token %}
{% if form.errors %}
<div class="alert alert-danger alert-icon alert-icon-border alert-dismissible" role="alert">
<div class="icon"><span class="mdi mdi-close-circle-o"></span></div>
<div class="message">
{% for field, error in form.errors.items %}
{{ error }}<br />
{% endfor %}
<button class="btn-close" type="button" data-dismiss="alert" aria-label="Close"></button>
</div>
</div>
{% endif %}
<div class="row">
<div class="col-sm-4">
{% bootstrap_form form %}
</div>
</div>
<div class="form-actions-no-box">
<a class="btn btn-grey" href="{% url 'idhub:admin_services' %}">{% translate "Cancel" %}</a>
<input class="btn btn-green-admin" type="submit" name="submit" value="{% translate 'Save' %}" />
</div>
</form>
{% endblock %}

View File

@ -0,0 +1,40 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
<div class="row mt-5">
<div class="col">
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Service' %}</button></th>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Description' %}</button></th>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Rol' %}</button></th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{% for service in services.all %}
<tr>
<td>{{ service.domain }}</td>
<td>{{ service.description }}</td>
<td>{{ service.rol.name }}</td>
<td><a href="{% url 'idhub:admin_service_edit' service.id %}" title="{% trans 'Edit' %}"><i class="bi bi-pencil-square"></i></a></td>
<td><a href="{% url 'idhub:admin_service_del' service.id %}" title="{% trans 'Delete' %}"><i class="bi bi-trash"></i></a></td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="form-actions-no-box">
<a class="btn btn-green-admin" href="{% url 'idhub:admin_service_new' %}">{% translate "Add Service" %} <i class="bi bi-plus"></i></a>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,125 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<div class="row">
<div class="col">
<h3 class="{% if not object.is_active %}alert alert-danger{% endif %}">
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
</div>
<div class="col text-center">
<a href="{% url 'idhub:admin_people_edit' object.id %}" type="button" class="btn btn-green-admin">{% trans 'Modify' %}</a>
<a href="{% url 'idhub:admin_people_activate' object.id %}" type="button" class="btn btn-yellow ms-3 me-3">{% if object.is_active %}{% trans 'Deactivate' %}{% else %}{% trans 'Activate' %}{% endif %}</a>
<a href="#" type="button" class="btn btn-orange" data-bs-toggle="modal" data-bs-target="#confirm-delete">{% trans 'Delete' %}</a>
</div>
</div>
<div class="row">
<div class="col">
<div class="card mb-3">
<div class="card-body">
<div class="row border-bottom">
<div class="col-3">
First Name:
</div>
<div class="col-9 text-secondary">
{{ object.first_name }}
</div>
</div>
<div class="row border-bottom mt-3">
<div class="col-3">
Last Name:
</div>
<div class="col-9 text-secondary">
{{ object.last_name }}
</div>
</div>
<div class="row mt-3">
<div class="col-3">
Email:
</div>
<div class="col-9 text-secondary">
{{ object.email }}
</div>
</div>
</div>
</div>
</div>
<div class="col text-center">
<i class="bi bi-person-circle" style="font-size: 100px;"></i>
</div>
</div>
<hr />
<div class="row">
<div class="col">
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Membership' %}</button></th>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'From' %}</button></th>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'To' %}</button></th>
</tr>
</thead>
<tbody>
{% for membership in object.memberships.all %}
<tr>
<td>{{ membership.get_type }}</td>
<td>{{ membership.start_date|default:'' }}</td>
<td>{{ membership.end_date|default:'' }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<div class="row mt-5">
<div class="col">
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Rol' %}</button></th>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Description' %}</button></th>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Service' %}</button></th>
</tr>
</thead>
<tbody>
{% for rol in object.roles.all %}
<tr>
<td>{{ rol.service.rol.name }}</td>
<td>{{ rol.service.description }}</td>
<td>{{ rol.service.domain }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal" id="confirm-delete" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">{% trans 'Delete user' %} {{ object.username }}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
{% trans 'Are you sure that you want delete this user?' %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Clancel</button>
<a href="{% url 'idhub:admin_people_delete' object.id %}" type="button" class="btn btn-danger">{% trans 'Delete' %}</a>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,98 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% load django_bootstrap5 %}
<form role="form" method="post">
{% csrf_token %}
{% if form.errors %}
<div class="alert alert-danger alert-icon alert-icon-border alert-dismissible" role="alert">
<div class="icon"><span class="mdi mdi-close-circle-o"></span></div>
<div class="message">
<button class="close" type="button" data-dismiss="alert" aria-label="Close">
<span class="mdi mdi-close" aria-hidden="true"></span>
</button>
{% for field, error in form.errors.items %}
{{ error }}
{% endfor %}
</div>
</div>
{% endif %}
{% bootstrap_form form %}
<div class="form-actions-no-box">
<a class="btn btn-grey" href="{% url 'idhub:admin_people' object.id %}">{% translate "Cancel" %}</a>
<input class="btn btn-green-admin" type="submit" name="submit" value="{% translate 'Save' %}" />
</div>
</form>
<hr />
<div class="row mt-5">
<div class="col">
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Membership' %}</button></th>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'From' %}</button></th>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'To' %}</button></th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{% for membership in object.memberships.all %}
<tr>
<td>{{ membership.get_type }}</td>
<td>{{ membership.start_date|default:'' }}</td>
<td>{{ membership.end_date|default:'' }}</td>
<td><a href="{% url 'idhub:admin_people_membership_edit' membership.id %}" title="{% trans 'Edit' %}"><i class="bi bi-pencil-square"></i></a></td>
<td><a href="{% url 'idhub:admin_people_membership_del' membership.id %}" title="{% trans 'Delete' %}"><i class="bi bi-trash"></i></a></td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="form-actions-no-box">
<a class="btn btn-green-admin" href="{% url 'idhub:admin_people_membership_new' object.id %}">{% translate "Add membership" %} <i class="bi bi-plus"></i></a>
</div>
</div>
</div>
</div>
<div class="row mt-5 mb-3">
<div class="col">
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Rol' %}</button></th>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Description' %}</button></th>
<th scope="col"><button type="button" class="btn btn-grey border border-dark">{% trans 'Service' %}</button></th>
<th scope="col"></th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{% for rol in object.roles.all %}
<tr>
<td>{{ rol.service.rol.name }}</td>
<td>{{ rol.service.description }}</td>
<td>{{ rol.service.domain }}</td>
<td><a href="{% url 'idhub:admin_people_rol_edit' rol.id %}" title="{% trans 'Edit' %}"><i class="bi bi-pencil-square"></i></a></td>
<td><a href="{% url 'idhub:admin_people_rol_del' rol.id %}" title="{% trans 'Delete' %}"><i class="bi bi-trash"></i></a></td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="form-actions-no-box">
<a class="btn btn-green-admin" href="{% url 'idhub:admin_people_rol_new' object.id %}">{% translate "Add Rol" %} <i class="bi bi-plus"></i></a>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% endblock %}

View File

@ -0,0 +1,9 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% endblock %}

View File

@ -1,5 +0,0 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
{% endblock %}

View File

@ -1,5 +0,0 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
{% endblock %}

View File

@ -1,5 +0,0 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
{% endblock %}

View File

@ -1,5 +0,0 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
{% endblock %}

View File

@ -1,5 +0,0 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
{% endblock %}

View File

@ -1,5 +0,0 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
{% endblock %}

View File

@ -1,5 +0,0 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
{% endblock %}

View File

@ -1,5 +0,0 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
{% endblock %}

View File

@ -1,5 +0,0 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
{% endblock %}

View File

@ -1,5 +0,0 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
{% endblock %}

View File

@ -1,5 +0,0 @@
{% extends "idhub/base_admin.html" %}
{% load i18n %}
{% block content %}
{% endblock %}

View File

@ -128,10 +128,9 @@
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
{% block messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags|default:'info' }} alert-dismissible fade show" role="alert">
<div class="alert {{ message.tags|default:'info' }} alert-dismissible fade show mt-3" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
</button>
</div>
{% endfor %}

View File

@ -77,7 +77,7 @@
</a>
<ul class="flex-column mb-2 ul_sidebar accordion-collapse {% if section == 'People' %}expanded{% else %}collapse{% endif %}" id="people" data-bs-parent="#sidebarMenu">
<li class="nav-item">
<a class="nav-link{% if path == 'admin_people' %} active2{% endif %}" href="{% url 'idhub:admin_people' %}">
<a class="nav-link{% if path == 'admin_people_list' %} active2{% endif %}" href="{% url 'idhub:admin_people_list' %}">
People list
</a>
</li>
@ -199,10 +199,9 @@
<main class="col-md-9 ms-sm-auto col-lg-10 px-md-4">
{% block messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags|default:'info' }} alert-dismissible fade show" role="alert">
<div class="alert {{ message.tags|default:'info' }} alert-dismissible fade show mt-3" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close">
</button>
</div>
{% endfor %}
@ -216,10 +215,6 @@
</div>
</div>
<h3>
<i class="{{ icon }}"></i>
{{ subtitle }}
</h3>
{% block content %}
{% endblock content %}
@ -227,9 +222,11 @@
</div>
</div>
<script src="/static/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/feather-icons@4.28.0/dist/feather.min.js" integrity="sha384-uO3SXW5IuS1ZpFPKugNNWqTZRRglnUJK6UAZ/gxOX80nxEkN9NcGZTftn6RzhGWE" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js" integrity="sha384-zNy6FEbO50N+Cg5wap8IKA4M/ZnLJgzc6w2NqACZaK0u0FXfOWRRJOnQtpZun8ha" crossorigin="anonymous"></script>
<script src="/static/js/dashboard.js"></script>
{% block script %}
<script src="{% static "js/jquery-3.3.1.slim.min.js" %}"></script>
<script src="{% static "js/popper.min.js" %}"></script>
<script src="{% static "js/bootstrap.min.js" %}"></script>
{% block extrascript %}{% endblock %}
{% endblock %}
</body>
</html>

View File

@ -0,0 +1,28 @@
{% extends "idhub/base.html" %}
{% load i18n %}
{% block content %}
{% load django_bootstrap5 %}
<form role="form" method="post">
{% csrf_token %}
{% if form.errors %}
<div class="alert alert-danger alert-icon alert-icon-border alert-dismissible" role="alert">
<div class="icon"><span class="mdi mdi-close-circle-o"></span></div>
<div class="message">
<button class="close" type="button" data-dismiss="alert" aria-label="Close">
<span class="mdi mdi-close" aria-hidden="true"></span>
</button>
{% for field, error in form.errors.items %}
{{ error }}
{% endfor %}
</div>
</div>
{% endif %}
{% bootstrap_form form %}
<div class="form-actions-no-box">
<a class="btn btn-secondary" href="{% url 'idhub:user_profile' %}">{% translate "Cancel" %}</a>
<input class="btn btn-success" type="submit" name="submit" value="{% translate 'Save' %}" />
</div>
</form>
{% endblock %}

View File

@ -1,5 +0,0 @@
{% extends "idhub/base.html" %}
{% load i18n %}
{% block content %}
{% endblock %}

View File

@ -52,14 +52,46 @@ urlpatterns = [
# Admin
path('admin/dashboard/', views_admin.AdminDashboardView.as_view(),
name='admin_dashboard'),
path('admin/people/', views_admin.AdminPeopleView.as_view(),
path('admin/people/', views_admin.AdminPeopleListView.as_view(),
name='admin_people_list'),
path('admin/people/<int:pk>', views_admin.AdminPeopleView.as_view(),
name='admin_people'),
path('admin/people/<int:pk>/edit', views_admin.AdminPeopleEditView.as_view(),
name='admin_people_edit'),
path('admin/people/<int:pk>/del', views_admin.AdminPeopleDeleteView.as_view(),
name='admin_people_delete'),
path('admin/people/<int:pk>/activate', views_admin.AdminPeopleActivateView.as_view(),
name='admin_people_activate'),
path('admin/people/new/', views_admin.AdminPeopleRegisterView.as_view(),
name='admin_people_new'),
path('admin/people/<int:pk>/membership/new/', views_admin.AdminPeopleMembershipRegisterView.as_view(),
name='admin_people_membership_new'),
path('admin/membership/<int:pk>/edit/', views_admin.AdminPeopleMembershipEditView.as_view(),
name='admin_people_membership_edit'),
path('admin/membership/<int:pk>/del/', views_admin.AdminPeopleMembershipDeleteView.as_view(),
name='admin_people_membership_del'),
path('admin/people/<int:pk>/rol/new/', views_admin.AdminPeopleRolRegisterView.as_view(),
name='admin_people_rol_new'),
path('admin/people/<int:pk>/rol/edit/', views_admin.AdminPeopleRolEditView.as_view(),
name='admin_people_rol_edit'),
path('admin/people/<int:pk>/rol/del/', views_admin.AdminPeopleRolDeleteView.as_view(),
name='admin_people_rol_del'),
path('admin/roles/', views_admin.AdminRolesView.as_view(),
name='admin_roles'),
path('admin/roles/new', views_admin.AdminRolRegisterView.as_view(),
name='admin_rol_new'),
path('admin/roles/<int:pk>', views_admin.AdminRolEditView.as_view(),
name='admin_rol_edit'),
path('admin/roles/<int:pk>/del', views_admin.AdminRolDeleteView.as_view(),
name='admin_rol_del'),
path('admin/services/', views_admin.AdminServicesView.as_view(),
name='admin_services'),
path('admin/services/new', views_admin.AdminServiceRegisterView.as_view(),
name='admin_service_new'),
path('admin/services/<int:pk>', views_admin.AdminServiceEditView.as_view(),
name='admin_service_edit'),
path('admin/services/<int:pk>/del', views_admin.AdminServiceDeleteView.as_view(),
name='admin_service_del'),
path('admin/credentials/', views_admin.AdminCredentialsView.as_view(),
name='admin_credentials'),
path('admin/credentials/new/', views_admin.AdminIssueCredentialsView.as_view(),

10
idhub/user/forms.py Normal file
View File

@ -0,0 +1,10 @@
from django import forms
from django.contrib.auth.models import User
class ProfileForm(forms.ModelForm):
MANDATORY_FIELDS = ['first_name', 'last_name', 'email']
class Meta:
model = User
fields = ('first_name', 'last_name', 'email')

View File

@ -1,8 +1,11 @@
import logging
from django.utils.translation import gettext_lazy as _
from django.views.generic.edit import UpdateView
from django.views.generic.base import TemplateView
from django.urls import reverse_lazy
from django.contrib import messages
from idhub.user.forms import ProfileForm
from idhub.mixins import UserView
@ -11,56 +14,62 @@ class MyProfile(UserView):
section = "MyProfile"
class MyWallet(UserView):
class MyWallet(UserView, TemplateView):
title = _("My Wallet")
section = "MyWallet"
class UserDashboardView(UserView):
template_name = "idhub/user_dashboard.html"
class UserDashboardView(UserView, TemplateView):
template_name = "idhub/user/dashboard.html"
title = _('Dashboard')
subtitle = _('Success')
icon = 'bi bi-bell'
section = "Home"
class UserProfileView(MyProfile):
template_name = "idhub/user_profile.html"
class UserProfileView(MyProfile, UpdateView):
template_name = "idhub/user/profile.html"
subtitle = _('My personal Data')
icon = 'bi bi-person'
from_class = ProfileForm
fields = ('first_name', 'last_name', 'email')
success_url = reverse_lazy('idhub:user_profile')
def get_object(self):
return self.request.user
class UserRolesView(MyProfile):
template_name = "idhub/user_roles.html"
class UserRolesView(MyProfile, TemplateView):
template_name = "idhub/user/roles.html"
subtitle = _('My roles')
icon = 'fa-brands fa-critical-role'
class UserGDPRView(MyProfile):
template_name = "idhub/user_gdpr.html"
class UserGDPRView(MyProfile, TemplateView):
template_name = "idhub/user/gdpr.html"
subtitle = _('GDPR info')
icon = 'bi bi-file-earmark-medical'
class UserIdentitiesView(MyWallet):
template_name = "idhub/user_identities.html"
template_name = "idhub/user/identities.html"
subtitle = _('Identities (DID)')
icon = 'bi bi-patch-check-fill'
class UserCredentialsView(MyWallet):
template_name = "idhub/user_credentials.html"
template_name = "idhub/user/credentials.html"
subtitle = _('Credentials')
icon = 'bi bi-patch-check-fill'
class UserCredentialsRequiredView(MyWallet):
template_name = "idhub/user_credentials_required.html"
template_name = "idhub/user/credentials_required.html"
subtitle = _('Credentials required')
icon = 'bi bi-patch-check-fill'
class UserCredentialsPresentationView(MyWallet):
template_name = "idhub/user_credentials_presentation.html"
template_name = "idhub/user/credentials_presentation.html"
subtitle = _('Credentials Presentation')
icon = 'bi bi-patch-check-fill'

View File

@ -10,7 +10,7 @@ class LoginView(auth_views.LoginView):
'success_url': reverse_lazy('idhub:user_dashboard'),
}
def get(self, request):
def get(self, request, *args, **kwargs):
if request.GET.get('next'):
self.extra_context['success_url'] = request.GET.get('next')
return super().get(request)
return super().get(request, *args, **kwargs)

View File

@ -1,3 +1,5 @@
django==4.2.5
django-bootstrap4==23.2
django-bootstrap5==23.3
django-extensions==3.2.3
black==23.9.1
python-decouple==3.8

View File

@ -9,8 +9,14 @@ https://docs.djangoproject.com/en/4.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""
import os
from ast import literal_eval
from pathlib import Path
from django.contrib.messages import constants as messages
from decouple import config, Csv
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
@ -20,12 +26,35 @@ BASE_DIR = Path(__file__).resolve().parent.parent
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-os^a#c(i*z8*=o4#b%xsno97_!pqsv*or_5&lcga7&+u53(p92'
SECRET_KEY = config('SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
DEBUG = config('DEBUG', default=False, cast=bool)
ALLOWED_HOSTS = []
ALLOWED_HOSTS = config('ALLOWED_HOSTS', default=[], cast=Csv())
DOMAIN = config("DOMAIN", "http://localhost")
DEFAULT_FROM_EMAIL = config(
'DEFAULT_FROM_EMAIL', default='webmaster@localhost')
EMAIL_HOST = config('EMAIL_HOST', default='localhost')
EMAIL_HOST_USER = config('EMAIL_HOST_USER', default='')
EMAIL_HOST_PASSWORD = config('EMAIL_HOST_PASSWORD', default='')
EMAIL_PORT = config('EMAIL_PORT', default=25, cast=int)
EMAIL_USE_TLS = config('EMAIL_USE_TLS', default=False, cast=bool)
EMAIL_BACKEND = config('EMAIL_BACKEND', default='django.core.mail.backends.smtp.EmailBackend')
EMAIL_FILE_PATH = config('EMAIL_FILE_PATH', default='/tmp/app-messages')
ADMINS = config('ADMINS', default='[]', cast=literal_eval)
MANAGERS = config('MANAGERS', default='[]', cast=literal_eval)
# Application definition
@ -38,7 +67,7 @@ INSTALLED_APPS = [
'django.contrib.messages',
'django.contrib.staticfiles',
'django_extensions',
'bootstrap4',
'django_bootstrap5',
'idhub'
]
@ -81,6 +110,11 @@ DATABASES = {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
# 'default': config(
# 'DATABASE_URL',
# default='sqlite:///' + os.path.join(BASE_DIR, 'db.sqlite3'),
# cast=db_url
# )
}
@ -108,7 +142,7 @@ AUTH_PASSWORD_VALIDATORS = [
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
TIME_ZONE = config('TIME_ZONE', 'UTC')
USE_I18N = True
@ -118,10 +152,24 @@ USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/
STATIC_URL = 'static/'
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
STATIC_ROOT = config('STATIC_ROOT')
MEDIA_ROOT = config('MEDIA_ROOT', default="idhub/upload")
FIXTURE_DIRS = (os.path.join(BASE_DIR, 'fixtures'),)
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
LOGIN_REDIRECT_URL = 'idhub:user_dashboard'
LOGOUT_REDIRECT_URL = 'idhub:login'
MESSAGE_TAGS = {
messages.DEBUG: 'alert-secondary',
messages.INFO: 'alert-info',
messages.SUCCESS: 'alert-success',
messages.WARNING: 'alert-warning',
messages.ERROR: 'alert-danger',
}