diff --git a/idhub/admin/forms.py b/idhub/admin/forms.py index c54929b..a6aec4c 100644 --- a/idhub/admin/forms.py +++ b/idhub/admin/forms.py @@ -19,6 +19,33 @@ from idhub.models import ( from idhub_auth.models import User +class TermsConditionsForm(forms.Form): + accept = forms.BooleanField( + label=_("Accept terms and conditions of the service"), + required=False + ) + + def __init__(self, *args, **kwargs): + self.user = kwargs.pop('user', None) + super().__init__(*args, **kwargs) + + def clean(self): + data = self.cleaned_data + if data.get("accept"): + self.user.accept_gdpr = True + else: + self.user.accept_gdpr = False + return data + + def save(self, commit=True): + + if commit: + self.user.save() + return self.user + + return + + class ImportForm(forms.Form): did = forms.ChoiceField(label=_("Did"), choices=[]) schema = forms.ChoiceField(label=_("Schema"), choices=[]) diff --git a/idhub/admin/views.py b/idhub/admin/views.py index 45640d4..47b353c 100644 --- a/idhub/admin/views.py +++ b/idhub/admin/views.py @@ -29,6 +29,7 @@ from idhub.email.views import NotifyActivateUserByEmail from idhub.admin.forms import ( ImportForm, MembershipForm, + TermsConditionsForm, SchemaForm, UserRolForm, ) @@ -48,6 +49,26 @@ from idhub.models import ( ) +class TermsAndConditionsView(AdminView, FormView): + template_name = "idhub/admin/terms_conditions.html" + title = _("GDPR") + section = "" + subtitle = _('Accept Terms and Conditions') + icon = 'bi bi-file-earmark-medical' + form_class = TermsConditionsForm + success_url = reverse_lazy('idhub:admin_dashboard') + + def get_form_kwargs(self): + kwargs = super().get_form_kwargs() + kwargs['user'] = self.request.user + kwargs['initial'] = {"accept": self.request.user.accept_gdpr} + return kwargs + + def form_valid(self, form): + user = form.save() + return super().form_valid(form) + + class DobleFactorAuthView(AdminView, View): url = reverse_lazy('idhub:admin_dashboard') diff --git a/idhub/migrations/0001_initial.py b/idhub/migrations/0001_initial.py index 355af60..157a614 100644 --- a/idhub/migrations/0001_initial.py +++ b/idhub/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.5 on 2024-01-17 16:56 +# Generated by Django 4.2.5 on 2024-01-20 12:47 from django.conf import settings from django.db import migrations, models diff --git a/idhub/mixins.py b/idhub/mixins.py index 8692c2d..a461a63 100644 --- a/idhub/mixins.py +++ b/idhub/mixins.py @@ -23,6 +23,27 @@ class Http403(PermissionDenied): class UserView(LoginRequiredMixin): login_url = "/login/" wallet = False + path_terms = [ + 'admin_terms_and_conditions', + 'user_terms_and_conditions', + 'user_gdpr', + ] + + def get(self, request, *args, **kwargs): + response = super().get(request, *args, **kwargs) + url = self.check_gdpr() + if url: + return url + + return response + + def post(self, request, *args, **kwargs): + response = super().post(request, *args, **kwargs) + url = self.check_gdpr() + if url: + return url + + return response def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) @@ -37,6 +58,14 @@ class UserView(LoginRequiredMixin): }) return context + def check_gdpr(self): + if not self.request.user.accept_gdpr: + url = reverse_lazy("idhub:user_terms_and_conditions") + if self.request.user.is_admin: + url = reverse_lazy("idhub:admin_terms_and_conditions") + if resolve(self.request.path).url_name not in self.path_terms: + return redirect(url) + class AdminView(UserView): @@ -50,8 +79,8 @@ class AdminView(UserView): def check_valid_user(self): if not self.request.user.is_admin: - raise Http403 + raise Http403() if self.request.session.get("2fauth"): - raise Http403 + raise Http403() diff --git a/idhub/templates/idhub/admin/terms_conditions.html b/idhub/templates/idhub/admin/terms_conditions.html new file mode 100644 index 0000000..51f8b6c --- /dev/null +++ b/idhub/templates/idhub/admin/terms_conditions.html @@ -0,0 +1,57 @@ +{% extends "idhub/base_admin.html" %} +{% load i18n %} + +{% block content %} +

+ + {{ subtitle }} +

+{% load django_bootstrap5 %} +
+{% csrf_token %} +{% if form.errors %} + +{% endif %} +
+
+ You must read the terms and conditions of this service and accept the + Read GDPR +
+
+
+
+ {% bootstrap_form form %} +
+
+
+ {% translate "Cancel" %} + +
+ +
+ + +{% endblock %} diff --git a/idhub/templates/idhub/user/gdpr.html b/idhub/templates/idhub/user/gdpr.html index 1ac25fd..16476b8 100644 --- a/idhub/templates/idhub/user/gdpr.html +++ b/idhub/templates/idhub/user/gdpr.html @@ -6,4 +6,7 @@ {{ subtitle }} +Gdpr info
+If you want accept or revoke the Gdpr go to: + Terms and conditions {% endblock %} diff --git a/idhub/templates/idhub/user/terms_conditions.html b/idhub/templates/idhub/user/terms_conditions.html new file mode 100644 index 0000000..8a02175 --- /dev/null +++ b/idhub/templates/idhub/user/terms_conditions.html @@ -0,0 +1,57 @@ +{% extends "idhub/base.html" %} +{% load i18n %} + +{% block content %} +

+ + {{ subtitle }} +

+{% load django_bootstrap5 %} +
+{% csrf_token %} +{% if form.errors %} + +{% endif %} +
+
+ You must read the terms and conditions of this service and accept the + Read GDPR +
+
+
+
+ {% bootstrap_form form %} +
+
+
+ {% translate "Cancel" %} + +
+ +
+ + +{% endblock %} diff --git a/idhub/urls.py b/idhub/urls.py index 9d8d72c..c4bbb86 100644 --- a/idhub/urls.py +++ b/idhub/urls.py @@ -17,7 +17,12 @@ Including another URLconf from django.contrib.auth import views as auth_views from django.views.generic import RedirectView from django.urls import path, reverse_lazy -from .views import LoginView, PasswordResetConfirmView, serve_did, DobleFactorSendView +from .views import ( + LoginView, + PasswordResetConfirmView, + serve_did, + DobleFactorSendView, +) from .admin import views as views_admin from .user import views as views_user # from .verification_portal import views as views_verification_portal @@ -91,6 +96,8 @@ urlpatterns = [ path('user/credentials_presentation/demand', views_user.DemandAuthorizationView.as_view(), name='user_demand_authorization'), + path('user/terms/', views_user.TermsAndConditionsView.as_view(), + name='user_terms_and_conditions'), # Admin path('admin/dashboard/', views_admin.DashboardView.as_view(), @@ -173,6 +180,8 @@ urlpatterns = [ name='admin_schemas_import_add'), path('admin/import', views_admin.ImportView.as_view(), name='admin_import'), + path('admin/terms/', views_admin.TermsAndConditionsView.as_view(), + name='admin_terms_and_conditions'), path('admin/import/new', views_admin.ImportAddView.as_view(), name='admin_import_add'), path('admin/auth/', views_admin.DobleFactorAuthView.as_view(), diff --git a/idhub/user/forms.py b/idhub/user/forms.py index e5530fa..89be994 100644 --- a/idhub/user/forms.py +++ b/idhub/user/forms.py @@ -16,6 +16,33 @@ class ProfileForm(forms.ModelForm): fields = ('first_name', 'last_name', 'email') +class TermsConditionsForm(forms.Form): + accept = forms.BooleanField( + label=_("Accept terms and conditions of the service"), + required=False + ) + + def __init__(self, *args, **kwargs): + self.user = kwargs.pop('user', None) + super().__init__(*args, **kwargs) + + def clean(self): + data = self.cleaned_data + if data.get("accept"): + self.user.accept_gdpr = True + else: + self.user.accept_gdpr = False + return data + + def save(self, commit=True): + + if commit: + self.user.save() + return self.user + + return + + class RequestCredentialForm(forms.Form): did = forms.ChoiceField(label=_("Did"), choices=[]) credential = forms.ChoiceField(label=_("Credential"), choices=[]) diff --git a/idhub/user/views.py b/idhub/user/views.py index 37144cb..c8147f8 100644 --- a/idhub/user/views.py +++ b/idhub/user/views.py @@ -15,7 +15,8 @@ from django.contrib import messages from idhub.user.forms import ( ProfileForm, RequestCredentialForm, - DemandAuthorizationForm + DemandAuthorizationForm, + TermsConditionsForm ) from idhub.mixins import UserView from idhub.models import DID, VerificableCredential, Event @@ -88,6 +89,26 @@ class CredentialsView(MyWallet, TemplateView): }) return context + +class TermsAndConditionsView(UserView, FormView): + template_name = "idhub/user/terms_conditions.html" + title = _("GDPR") + section = "" + subtitle = _('Accept Terms and Conditions') + icon = 'bi bi-file-earmark-medical' + form_class = TermsConditionsForm + success_url = reverse_lazy('idhub:user_dashboard') + + def get_form_kwargs(self): + kwargs = super().get_form_kwargs() + kwargs['user'] = self.request.user + kwargs['initial'] = {"accept": self.request.user.accept_gdpr} + return kwargs + + def form_valid(self, form): + user = form.save() + return super().form_valid(form) + class CredentialView(MyWallet, TemplateView): template_name = "idhub/user/credential.html" diff --git a/idhub_auth/migrations/0001_initial.py b/idhub_auth/migrations/0001_initial.py index 84a93da..dda3789 100644 --- a/idhub_auth/migrations/0001_initial.py +++ b/idhub_auth/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.5 on 2024-01-17 16:56 +# Generated by Django 4.2.5 on 2024-01-20 12:47 from django.db import migrations, models @@ -50,6 +50,7 @@ class Migration(migrations.Migration): ), ('encrypted_sensitive_data', models.CharField(max_length=255)), ('salt', models.CharField(max_length=255)), + ('accept_gdpr', models.BooleanField(default=False)), ], options={ 'abstract': False, diff --git a/idhub_auth/models.py b/idhub_auth/models.py index 38224b2..83df00b 100644 --- a/idhub_auth/models.py +++ b/idhub_auth/models.py @@ -51,6 +51,7 @@ class User(AbstractBaseUser): last_name = models.CharField(_("Last name"), max_length=255, blank=True, null=True) encrypted_sensitive_data = models.CharField(max_length=255) salt = models.CharField(max_length=255) + accept_gdpr = models.BooleanField(default=False) objects = UserManager() diff --git a/oidc4vp/migrations/0001_initial.py b/oidc4vp/migrations/0001_initial.py index b1fceed..4533728 100644 --- a/oidc4vp/migrations/0001_initial.py +++ b/oidc4vp/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.5 on 2024-01-17 16:56 +# Generated by Django 4.2.5 on 2024-01-20 12:47 from django.conf import settings from django.db import migrations, models diff --git a/promotion/migrations/0001_initial.py b/promotion/migrations/0001_initial.py index ad2ac86..2635351 100644 --- a/promotion/migrations/0001_initial.py +++ b/promotion/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.5 on 2024-01-17 16:56 +# Generated by Django 4.2.5 on 2024-01-20 12:47 from django.db import migrations, models import django.db.models.deletion