From 6babea9f55fa44e2856ce8f517fffda2a17c8e1b Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 19 Jan 2024 09:11:02 +0100 Subject: [PATCH 1/9] drop search box --- idhub/templates/idhub/base.html | 3 --- idhub/templates/idhub/base_admin.html | 3 --- 2 files changed, 6 deletions(-) diff --git a/idhub/templates/idhub/base.html b/idhub/templates/idhub/base.html index 390cb33..12b6072 100644 --- a/idhub/templates/idhub/base.html +++ b/idhub/templates/idhub/base.html @@ -138,9 +138,6 @@

{{ title }}

-
- -
diff --git a/idhub/templates/idhub/base_admin.html b/idhub/templates/idhub/base_admin.html index c97f165..271d6d5 100644 --- a/idhub/templates/idhub/base_admin.html +++ b/idhub/templates/idhub/base_admin.html @@ -170,9 +170,6 @@

{{ title }}

-
- -
From b031f2ac0856c649a53893a79fedfaf74d0651c4 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 19 Jan 2024 10:59:35 +0100 Subject: [PATCH 2/9] admin2fauth --- idhub/admin/views.py | 18 ++++++++++++++++++ idhub/mixins.py | 3 +++ idhub/urls.py | 2 ++ idhub/views.py | 3 +++ 4 files changed, 26 insertions(+) diff --git a/idhub/admin/views.py b/idhub/admin/views.py index 44e36af..b7a13df 100644 --- a/idhub/admin/views.py +++ b/idhub/admin/views.py @@ -48,6 +48,24 @@ from idhub.models import ( ) +class DobleFactorAuthView(AdminView): + url = reverse_lazy('idhub:admin_dashboard') + + def get(self, request, *args, **kwargs): + import pdb; pdb.set_trace() + if not self.request.session.get("2fauth"): + return redirect(self.url) + + if self.request.session.get("2fauth") == '0c9116a7-c6e5-41d7-bbf0-e8492cdfca23' + if not request.user.is_admin: + return redirect(url) + + if self.request.session.get("2fauth"): + return redirect(reverse_lazy("idhub:login")) + + return super().get(request, *args, **kwargs) + + class DashboardView(AdminView, SingleTableView): template_name = "idhub/admin/dashboard.html" table_class = DashboardTable diff --git a/idhub/mixins.py b/idhub/mixins.py index 68b7344..f118b1e 100644 --- a/idhub/mixins.py +++ b/idhub/mixins.py @@ -30,4 +30,7 @@ class AdminView(UserView): url = reverse_lazy('idhub:user_dashboard') return redirect(url) + if self.request.session.get("2fauth"): + return redirect(reverse_lazy("idhub:login")) + return super().get(request, *args, **kwargs) diff --git a/idhub/urls.py b/idhub/urls.py index 7f983c3..3583ac8 100644 --- a/idhub/urls.py +++ b/idhub/urls.py @@ -175,6 +175,8 @@ urlpatterns = [ name='admin_import'), path('admin/import/new', views_admin.ImportAddView.as_view(), name='admin_import_add'), + path('admin/auth/', views_admin.DobleFactorAuthView.as_view(), + name='admin_2fauth'), path('did-registry//did.json', serve_did) diff --git a/idhub/views.py b/idhub/views.py index f513353..04e8c21 100644 --- a/idhub/views.py +++ b/idhub/views.py @@ -1,3 +1,4 @@ +import uuid from django.shortcuts import get_object_or_404 from django.urls import reverse_lazy from django.conf import settings @@ -41,6 +42,8 @@ class LoginView(auth_views.LoginView): # ) # cache.set("KEY_DIDS", encryption_key, None) cache.set("KEY_DIDS", sensitive_data_encryption_key, None) + # self.request.session["2fauth"] = uuid.uuid4() + self.request.session["2fauth"] = '0c9116a7-c6e5-41d7-bbf0-e8492cdfca23' self.request.session["key_did"] = user.encrypt_data( sensitive_data_encryption_key, From b9d596301d7a34a7f26a5ab96a6288a4019535d6 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 19 Jan 2024 20:33:28 +0100 Subject: [PATCH 3/9] add doble factor of authentication for admin user --- idhub/templates/auth/2fadmin.html | 19 ++++++++++++++ idhub/templates/auth/2fadmin_email.html | 26 +++++++++++++++++++ idhub/templates/auth/2fadmin_email.txt | 14 ++++++++++ .../templates/auth/2fadmin_email_subject.txt | 3 +++ 4 files changed, 62 insertions(+) create mode 100644 idhub/templates/auth/2fadmin.html create mode 100644 idhub/templates/auth/2fadmin_email.html create mode 100644 idhub/templates/auth/2fadmin_email.txt create mode 100644 idhub/templates/auth/2fadmin_email_subject.txt diff --git a/idhub/templates/auth/2fadmin.html b/idhub/templates/auth/2fadmin.html new file mode 100644 index 0000000..4dc2ae6 --- /dev/null +++ b/idhub/templates/auth/2fadmin.html @@ -0,0 +1,19 @@ +{% extends "auth/login_base.html" %} +{% load i18n django_bootstrap5 %} + +{% block login_content %} + +
+
+

{% trans 'Doble Factor of Authentication' %}

+
+
+ +
+
+
+ {% trans "We have sent an email with a link that you have to select in order to login." %} +
+
+
+{% endblock %} diff --git a/idhub/templates/auth/2fadmin_email.html b/idhub/templates/auth/2fadmin_email.html new file mode 100644 index 0000000..d2253c5 --- /dev/null +++ b/idhub/templates/auth/2fadmin_email.html @@ -0,0 +1,26 @@ +{% load i18n %}{% autoescape off %} +

+{% blocktrans %}You're receiving this email because you try to access in {{ site_name }}.{% endblocktrans %} +

+ +

+{% trans "Please go to the following page" %} +

+ +

+{% block reset_link %} + +{{ protocol }}://{{ domain }}{% url 'idhub:admin_2fauth' admin2fauth=token %} + +{% endblock %} +

+ +

+{% trans "Thanks for using our site!" %} +

+ +

+{% blocktrans %}The {{ site_name }} team{% endblocktrans %} +

+ +{% endautoescape %} diff --git a/idhub/templates/auth/2fadmin_email.txt b/idhub/templates/auth/2fadmin_email.txt new file mode 100644 index 0000000..a9ef3e5 --- /dev/null +++ b/idhub/templates/auth/2fadmin_email.txt @@ -0,0 +1,14 @@ +{% load i18n %}{% autoescape off %} +{% blocktrans %}You're receiving this email because you try to access in {{ site_name }}.{% endblocktrans %} + +{% trans "Please go to the following page" %} +{% block reset_link %} +{{ protocol }}://{{ domain }}{% url 'idhub:admin_2fauth' admin2fauth=token %} +{% endblock %} +{% trans "Your username, in case you've forgotten:" %} {{ user.username }} + +{% trans "Thanks for using our site!" %} + +{% blocktrans %}The {{ site_name }} team{% endblocktrans %} + +{% endautoescape %} diff --git a/idhub/templates/auth/2fadmin_email_subject.txt b/idhub/templates/auth/2fadmin_email_subject.txt new file mode 100644 index 0000000..6d3bb21 --- /dev/null +++ b/idhub/templates/auth/2fadmin_email_subject.txt @@ -0,0 +1,3 @@ +{% load i18n %}{% autoescape off %} +{% blocktrans %}Authentication in {{ site_name }}{% endblocktrans %} +{% endautoescape %} \ No newline at end of file From 596b8eecd73d659264810f76a013a836b518dced Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Fri, 19 Jan 2024 20:37:17 +0100 Subject: [PATCH 4/9] view for doble factore sending email --- idhub/admin/views.py | 16 ++++++---------- idhub/email/views.py | 24 ++++++++++++++---------- idhub/urls.py | 5 +++-- idhub/views.py | 37 +++++++++++++++++++++++++++++++------ 4 files changed, 54 insertions(+), 28 deletions(-) diff --git a/idhub/admin/views.py b/idhub/admin/views.py index b7a13df..878594c 100644 --- a/idhub/admin/views.py +++ b/idhub/admin/views.py @@ -9,7 +9,7 @@ from django_tables2 import SingleTableView from django.conf import settings from django.utils.translation import gettext_lazy as _ -from django.views.generic.base import TemplateView +from django.views.generic.base import TemplateView, View from django.views.generic.edit import ( CreateView, DeleteView, @@ -48,22 +48,18 @@ from idhub.models import ( ) -class DobleFactorAuthView(AdminView): +class DobleFactorAuthView(AdminView, View): url = reverse_lazy('idhub:admin_dashboard') def get(self, request, *args, **kwargs): - import pdb; pdb.set_trace() if not self.request.session.get("2fauth"): return redirect(self.url) - if self.request.session.get("2fauth") == '0c9116a7-c6e5-41d7-bbf0-e8492cdfca23' - if not request.user.is_admin: - return redirect(url) + if self.request.session.get("2fauth") == str(kwargs.get("admin2fauth")): + self.request.session.pop("2fauth", None) + return redirect(self.url) - if self.request.session.get("2fauth"): - return redirect(reverse_lazy("idhub:login")) - - return super().get(request, *args, **kwargs) + return redirect(reverse_lazy("idhub:login")) class DashboardView(AdminView, SingleTableView): diff --git a/idhub/email/views.py b/idhub/email/views.py index 72e0daa..f14e2a5 100644 --- a/idhub/email/views.py +++ b/idhub/email/views.py @@ -13,7 +13,11 @@ logger = logging.getLogger(__name__) class NotifyActivateUserByEmail: - def get_email_context(self, user): + subject_template_name = 'idhub/admin/registration/activate_user_subject.txt' + email_template_name = 'idhub/admin/registration/activate_user_email.txt' + html_email_template_name = 'idhub/admin/registration/activate_user_email.html' + + def get_email_context(self, user, token): """ Define a new context with a token for put in a email when send a email for add a new password @@ -22,35 +26,35 @@ class NotifyActivateUserByEmail: current_site = get_current_site(self.request) site_name = current_site.name domain = current_site.domain + if not token: + token = default_token_generator.make_token(user) + context = { 'email': user.email, 'domain': domain, 'site_name': site_name, 'uid': urlsafe_base64_encode(force_bytes(user.pk)), 'user': user, - 'token': default_token_generator.make_token(user), + 'token': token, 'protocol': protocol, } return context - def send_email(self, user): + def send_email(self, user, token=None): """ Send a email when a user is activated. """ - context = self.get_email_context(user) - subject_template_name = 'idhub/admin/registration/activate_user_subject.txt' - email_template_name = 'idhub/admin/registration/activate_user_email.txt' - html_email_template_name = 'idhub/admin/registration/activate_user_email.html' - subject = loader.render_to_string(subject_template_name, context) + context = self.get_email_context(user, token) + subject = loader.render_to_string(self.subject_template_name, context) # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) - body = loader.render_to_string(email_template_name, context) + body = loader.render_to_string(self.email_template_name, context) from_email = settings.DEFAULT_FROM_EMAIL to_email = user.email email_message = EmailMultiAlternatives( subject, body, from_email, [to_email]) - html_email = loader.render_to_string(html_email_template_name, context) + html_email = loader.render_to_string(self.html_email_template_name, context) email_message.attach_alternative(html_email, 'text/html') try: if settings.DEVELOPMENT: diff --git a/idhub/urls.py b/idhub/urls.py index 3583ac8..9d8d72c 100644 --- a/idhub/urls.py +++ b/idhub/urls.py @@ -17,7 +17,7 @@ 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 +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 @@ -175,8 +175,9 @@ urlpatterns = [ name='admin_import'), path('admin/import/new', views_admin.ImportAddView.as_view(), name='admin_import_add'), - path('admin/auth/', views_admin.DobleFactorAuthView.as_view(), + path('admin/auth/', views_admin.DobleFactorAuthView.as_view(), name='admin_2fauth'), + path('admin/auth/2f/', DobleFactorSendView.as_view(), name='confirm_send_2f'), path('did-registry//did.json', serve_did) diff --git a/idhub/views.py b/idhub/views.py index 04e8c21..7a525b1 100644 --- a/idhub/views.py +++ b/idhub/views.py @@ -1,14 +1,18 @@ import uuid -from django.shortcuts import get_object_or_404 -from django.urls import reverse_lazy + from django.conf import settings from django.core.cache import cache -from django.utils.translation import gettext_lazy as _ +from django.urls import reverse_lazy +from django.views.generic.base import TemplateView from django.contrib.auth import views as auth_views from django.contrib.auth import login as auth_login -from django.http import HttpResponseRedirect, HttpResponse +from django.utils.translation import gettext_lazy as _ +from django.shortcuts import get_object_or_404, redirect +from django.contrib.auth.mixins import LoginRequiredMixin +from django.http import HttpResponseRedirect, HttpResponse, Http404 from idhub.models import DID +from idhub.email.views import NotifyActivateUserByEmail from trustchain_idhub import settings @@ -42,8 +46,9 @@ class LoginView(auth_views.LoginView): # ) # cache.set("KEY_DIDS", encryption_key, None) cache.set("KEY_DIDS", sensitive_data_encryption_key, None) - # self.request.session["2fauth"] = uuid.uuid4() - self.request.session["2fauth"] = '0c9116a7-c6e5-41d7-bbf0-e8492cdfca23' + if not settings.DEVELOPMENT: + self.request.session["2fauth"] = str(uuid.uuid4()) + return redirect(reverse_lazy('idhub:confirm_send_2f')) self.request.session["key_did"] = user.encrypt_data( sensitive_data_encryption_key, @@ -72,3 +77,23 @@ def serve_did(request, did_id): retval = HttpResponse(document) retval.headers["Content-Type"] = "application/json" return retval + + +class DobleFactorSendView(LoginRequiredMixin, NotifyActivateUserByEmail, TemplateView): + template_name = 'auth/2fadmin.html' + subject_template_name = 'auth/2fadmin_email_subject.txt' + email_template_name = 'auth/2fadmin_email.txt' + html_email_template_name = 'auth/2fadmin_email.html' + + def get(self, request, *args, **kwargs): + if not request.user.is_admin: + raise Http404 + + f2auth = self.request.session.get("2fauth") + if not f2auth: + raise Http404 + + self.send_email(self.request.user, token=f2auth) + return super().get(request, *args, **kwargs) + + From be985b52e7e10613d752366b8bcbe3234cce62c3 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Sat, 20 Jan 2024 11:10:05 +0100 Subject: [PATCH 5/9] delete verification_portal --- idhub/verification_portal/__init__.py | 0 idhub/verification_portal/models.py | 24 ------------- idhub/verification_portal/views.py | 49 --------------------------- requirements.txt | 2 +- 4 files changed, 1 insertion(+), 74 deletions(-) delete mode 100644 idhub/verification_portal/__init__.py delete mode 100644 idhub/verification_portal/models.py delete mode 100644 idhub/verification_portal/views.py diff --git a/idhub/verification_portal/__init__.py b/idhub/verification_portal/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/idhub/verification_portal/models.py b/idhub/verification_portal/models.py deleted file mode 100644 index 0bd203a..0000000 --- a/idhub/verification_portal/models.py +++ /dev/null @@ -1,24 +0,0 @@ -from django.db import models - - -class VPVerifyRequest(models.Model): - """ - `nonce` is an opaque random string used to lookup verification requests. URL-safe. - Example: "UPBQ3JE2DGJYHP5CPSCRIGTHRTCYXMQPNQ" - `expected_credentials` is a JSON list of credential types that must be present in this VP. - Example: ["FinancialSituationCredential", "HomeConnectivitySurveyCredential"] - `expected_contents` is a JSON object that places optional constraints on the contents of the - returned VP. - Example: [{"FinancialSituationCredential": {"financial_vulnerability_score": "7"}}] - `action` is (for now) a JSON object describing the next steps to take if this verification - is successful. For example "send mail to with and " - Example: {"action": "send_mail", "params": {"to": "orders@somconnexio.coop", "subject": "New client", "body": ...} - `response` is a URL that the user's wallet will redirect the user to. - `submitted_on` is used (by a cronjob) to purge old entries that didn't complete verification - """ - nonce = models.CharField(max_length=50) - expected_credentials = models.CharField(max_length=255) - expected_contents = models.TextField() - action = models.TextField() - response_or_redirect = models.CharField(max_length=255) - submitted_on = models.DateTimeField(auto_now=True) diff --git a/idhub/verification_portal/views.py b/idhub/verification_portal/views.py deleted file mode 100644 index 486f4f7..0000000 --- a/idhub/verification_portal/views.py +++ /dev/null @@ -1,49 +0,0 @@ -import json - -from django.core.mail import send_mail -from django.http import HttpResponse, HttpResponseRedirect - -from utils.idhub_ssikit import verify_presentation -from .models import VPVerifyRequest -from django.shortcuts import get_object_or_404 -from more_itertools import flatten, unique_everseen - - -def verify(request): - assert request.method == "POST" - # TODO: incorporate request.POST["presentation_submission"] as schema definition - (presentation_valid, _) = verify_presentation(request.POST["vp_token"]) - if not presentation_valid: - raise Exception("Failed to verify signature on the given Verifiable Presentation.") - vp = json.loads(request.POST["vp_token"]) - nonce = vp["nonce"] - # "vr" = verification_request - vr = get_object_or_404(VPVerifyRequest, nonce=nonce) # TODO: return meaningful error, not 404 - # Get a list of all included verifiable credential types - included_credential_types = unique_everseen(flatten([ - vc["type"] for vc in vp["verifiableCredential"] - ])) - # Check that it matches what we requested - for requested_vc_type in json.loads(vr.expected_credentials): - if requested_vc_type not in included_credential_types: - raise Exception("You're missing some credentials we requested!") # TODO: return meaningful error - # Perform whatever action we have to do - action = json.loads(vr.action) - if action["action"] == "send_mail": - subject = action["params"]["subject"] - to_email = action["params"]["to"] - from_email = "noreply@verifier-portal" - body = request.POST["vp-token"] - send_mail( - subject, - body, - from_email, - [to_email] - ) - elif action["action"] == "something-else": - pass - else: - raise Exception("Unknown action!") - # OK! Your verifiable presentation was successfully presented. - return HttpResponseRedirect(vr.response_or_redirect) - diff --git a/requirements.txt b/requirements.txt index 0c859a8..61087e5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -16,4 +16,4 @@ pynacl==1.5.0 more-itertools==10.1.0 dj-database-url==2.1.0 ujson==5.9.0 -didkit-0.3.2-cp311-cp311-manylinux_2_34_x86_64.whl +./didkit-0.3.2-cp311-cp311-manylinux_2_34_x86_64.whl From e87db60b7e80c298f9270f9dd73eaf472657d96e Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Sat, 20 Jan 2024 11:36:45 +0100 Subject: [PATCH 6/9] urlparse domain --- utils/idhub_ssikit/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utils/idhub_ssikit/__init__.py b/utils/idhub_ssikit/__init__.py index 3521eba..85e6e2f 100644 --- a/utils/idhub_ssikit/__init__.py +++ b/utils/idhub_ssikit/__init__.py @@ -2,6 +2,7 @@ import asyncio import datetime import didkit import json +import urllib import jinja2 from django.template.backends.django import Template from django.template.loader import get_template @@ -29,7 +30,8 @@ def webdid_from_controller_key(key): keydid = keydid_from_controller_key(key) # "did:key:<...>" pubkeyid = keydid.rsplit(":")[-1] # <...> document = json.loads(asyncio.run(resolve_keydid(keydid))) # Documento DID en terminos "key" - webdid_url = f"did:web:{settings.DOMAIN}:did-registry:{pubkeyid}" # nueva URL: "did:web:idhub.pangea.org:<...>" + domain = urllib.parse.urlencode({"domain": settings.DOMAIN})[7:] + webdid_url = f"did:web:{domain}:did-registry:{pubkeyid}" # nueva URL: "did:web:idhub.pangea.org:<...>" webdid_url_owner = webdid_url + "#owner" # Reemplazamos los campos del documento DID necesarios: document["id"] = webdid_url From 8c5e6302b616fbe4666598ebcdf2a7d0c007be37 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Sat, 20 Jan 2024 12:26:19 +0100 Subject: [PATCH 7/9] add 403 exception for bad access --- idhub/admin/views.py | 14 ++++++++++++++ idhub/mixins.py | 33 +++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/idhub/admin/views.py b/idhub/admin/views.py index 878594c..45640d4 100644 --- a/idhub/admin/views.py +++ b/idhub/admin/views.py @@ -52,6 +52,7 @@ class DobleFactorAuthView(AdminView, View): url = reverse_lazy('idhub:admin_dashboard') def get(self, request, *args, **kwargs): + self.check_valid_user() if not self.request.session.get("2fauth"): return redirect(self.url) @@ -132,6 +133,7 @@ class PeopleView(People, TemplateView): class PeopleActivateView(PeopleView): def get(self, request, *args, **kwargs): + self.check_valid_user() self.pk = kwargs['pk'] self.object = get_object_or_404(self.model, pk=self.pk) @@ -153,6 +155,7 @@ class PeopleActivateView(PeopleView): class PeopleDeleteView(PeopleView): def get(self, request, *args, **kwargs): + self.check_valid_user() self.pk = kwargs['pk'] self.object = get_object_or_404(self.model, pk=self.pk) @@ -317,6 +320,7 @@ class PeopleMembershipDeleteView(PeopleView): model = Membership def get(self, request, *args, **kwargs): + self.check_valid_user() self.pk = kwargs['pk'] self.object = get_object_or_404(self.model, pk=self.pk) @@ -404,6 +408,7 @@ class PeopleRolDeleteView(PeopleView): model = UserRol def get(self, request, *args, **kwargs): + self.check_valid_user() self.pk = kwargs['pk'] self.object = get_object_or_404(self.model, pk=self.pk) user = self.object.user @@ -467,6 +472,7 @@ class RolDeleteView(AccessControl): model = Rol def get(self, request, *args, **kwargs): + self.check_valid_user() self.pk = kwargs['pk'] self.object = get_object_or_404(self.model, pk=self.pk) @@ -540,6 +546,7 @@ class ServiceDeleteView(AccessControl): model = Service def get(self, request, *args, **kwargs): + self.check_valid_user() self.pk = kwargs['pk'] self.object = get_object_or_404(self.model, pk=self.pk) @@ -584,6 +591,7 @@ class CredentialView(Credentials): class CredentialJsonView(Credentials): def get(self, request, *args, **kwargs): + self.check_valid_user() pk = kwargs['pk'] self.object = get_object_or_404( VerificableCredential, @@ -598,6 +606,7 @@ class RevokeCredentialsView(Credentials): success_url = reverse_lazy('idhub:admin_credentials') def get(self, request, *args, **kwargs): + self.check_valid_user() pk = kwargs['pk'] self.object = get_object_or_404( VerificableCredential, @@ -617,6 +626,7 @@ class DeleteCredentialsView(Credentials): success_url = reverse_lazy('idhub:admin_credentials') def get(self, request, *args, **kwargs): + self.check_valid_user() pk = kwargs['pk'] self.object = get_object_or_404( VerificableCredential, @@ -696,6 +706,7 @@ class DidDeleteView(Credentials, DeleteView): success_url = reverse_lazy('idhub:admin_dids') def get(self, request, *args, **kwargs): + self.check_valid_user() self.pk = kwargs['pk'] self.object = get_object_or_404(self.model, pk=self.pk) Event.set_EV_ORG_DID_DELETED_BY_ADMIN(self.object) @@ -734,6 +745,7 @@ class SchemasView(SchemasMix): class SchemasDeleteView(SchemasMix): def get(self, request, *args, **kwargs): + self.check_valid_user() self.pk = kwargs['pk'] self.object = get_object_or_404(Schemas, pk=self.pk) self.object.delete() @@ -744,6 +756,7 @@ class SchemasDeleteView(SchemasMix): class SchemasDownloadView(SchemasMix): def get(self, request, *args, **kwargs): + self.check_valid_user() self.pk = kwargs['pk'] self.object = get_object_or_404(Schemas, pk=self.pk) @@ -822,6 +835,7 @@ class SchemasImportView(SchemasMix): class SchemasImportAddView(SchemasMix): def get(self, request, *args, **kwargs): + self.check_valid_user() file_name = kwargs['file_schema'] schemas_files = os.listdir(settings.SCHEMAS_DIR) if not file_name in schemas_files: diff --git a/idhub/mixins.py b/idhub/mixins.py index f118b1e..8692c2d 100644 --- a/idhub/mixins.py +++ b/idhub/mixins.py @@ -3,6 +3,21 @@ 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.shortcuts import redirect +from django.http import Http404 +from django.core.exceptions import PermissionDenied + + + +class Http403(PermissionDenied): + status_code = 403 + default_detail = _('Permission denied. User is not authenticated') + default_code = 'forbidden' + + def __init__(self, detail=None, code=None): + if detail is not None: + self.detail = details or self.default_details + if code is not None: + self.code = code or self.default_code class UserView(LoginRequiredMixin): @@ -26,11 +41,17 @@ class UserView(LoginRequiredMixin): class AdminView(UserView): def get(self, request, *args, **kwargs): - if not request.user.is_admin: - url = reverse_lazy('idhub:user_dashboard') - return redirect(url) + self.check_valid_user() + return super().get(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + self.check_valid_user() + return super().post(request, *args, **kwargs) + + def check_valid_user(self): + if not self.request.user.is_admin: + raise Http403 if self.request.session.get("2fauth"): - return redirect(reverse_lazy("idhub:login")) - - return super().get(request, *args, **kwargs) + raise Http403 + From c577dd975c543658d83f07aa447ff961af4c415c Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Sat, 20 Jan 2024 15:06:30 +0100 Subject: [PATCH 8/9] first page for accept terms and conditions --- idhub/admin/forms.py | 27 +++++++++ idhub/admin/views.py | 21 +++++++ idhub/migrations/0001_initial.py | 2 +- idhub/mixins.py | 33 ++++++++++- .../idhub/admin/terms_conditions.html | 57 +++++++++++++++++++ idhub/templates/idhub/user/gdpr.html | 3 + .../idhub/user/terms_conditions.html | 57 +++++++++++++++++++ idhub/urls.py | 11 +++- idhub/user/forms.py | 27 +++++++++ idhub/user/views.py | 23 +++++++- idhub_auth/migrations/0001_initial.py | 3 +- idhub_auth/models.py | 1 + oidc4vp/migrations/0001_initial.py | 2 +- promotion/migrations/0001_initial.py | 2 +- 14 files changed, 261 insertions(+), 8 deletions(-) create mode 100644 idhub/templates/idhub/admin/terms_conditions.html create mode 100644 idhub/templates/idhub/user/terms_conditions.html 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 %} +
+
+ + +
+ + +{% 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 %} +
+
+ + +
+ + +{% 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 From eaca0e793aac9596ef6d46f8dbffb4b4a3879341 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Sat, 20 Jan 2024 15:08:58 +0100 Subject: [PATCH 9/9] clean template dirs --- .../musician/address_check_delete.html | 12 -- .../templates/musician/address_form.html | 20 --- .../templates/musician/addresses.html | 41 ----- .../templates/templates/musician/billing.html | 41 ----- .../musician/components/paginator.html | 29 ---- .../musician/components/table_paginator.html | 50 ------ .../components/usage_progress_bar.html | 22 --- .../templates/musician/dashboard.html | 161 ------------------ .../templates/musician/databases.html | 68 -------- .../templates/musician/domain_detail.html | 30 ---- .../templates/musician/mail_base.html | 32 ---- .../musician/mailbox_change_password.html | 15 -- .../musician/mailbox_check_delete.html | 15 -- .../templates/musician/mailbox_form.html | 30 ---- .../templates/musician/mailboxes.html | 46 ----- .../templates/musician/mailinglists.html | 46 ----- .../templates/templates/musician/profile.html | 65 ------- idhub/templates/templates/musician/saas.html | 56 ------ .../templates/musician/service_list.html | 28 --- 19 files changed, 807 deletions(-) delete mode 100644 idhub/templates/templates/musician/address_check_delete.html delete mode 100644 idhub/templates/templates/musician/address_form.html delete mode 100644 idhub/templates/templates/musician/addresses.html delete mode 100644 idhub/templates/templates/musician/billing.html delete mode 100644 idhub/templates/templates/musician/components/paginator.html delete mode 100644 idhub/templates/templates/musician/components/table_paginator.html delete mode 100644 idhub/templates/templates/musician/components/usage_progress_bar.html delete mode 100644 idhub/templates/templates/musician/dashboard.html delete mode 100644 idhub/templates/templates/musician/databases.html delete mode 100644 idhub/templates/templates/musician/domain_detail.html delete mode 100644 idhub/templates/templates/musician/mail_base.html delete mode 100644 idhub/templates/templates/musician/mailbox_change_password.html delete mode 100644 idhub/templates/templates/musician/mailbox_check_delete.html delete mode 100644 idhub/templates/templates/musician/mailbox_form.html delete mode 100644 idhub/templates/templates/musician/mailboxes.html delete mode 100644 idhub/templates/templates/musician/mailinglists.html delete mode 100644 idhub/templates/templates/musician/profile.html delete mode 100644 idhub/templates/templates/musician/saas.html delete mode 100644 idhub/templates/templates/musician/service_list.html diff --git a/idhub/templates/templates/musician/address_check_delete.html b/idhub/templates/templates/musician/address_check_delete.html deleted file mode 100644 index 27981d4..0000000 --- a/idhub/templates/templates/musician/address_check_delete.html +++ /dev/null @@ -1,12 +0,0 @@ -{% extends "musician/base.html" %} -{% load i18n %} - -{% block content %} -
- {% csrf_token %} -

{% blocktrans with address_name=object.full_address_name %}Are you sure that you want remove the address: "{{ address_name }}"?{% endblocktrans %}

-

{% trans 'WARNING: This action cannot be undone.' %}

- - {% trans 'Cancel' %} -
-{% endblock %} diff --git a/idhub/templates/templates/musician/address_form.html b/idhub/templates/templates/musician/address_form.html deleted file mode 100644 index de21067..0000000 --- a/idhub/templates/templates/musician/address_form.html +++ /dev/null @@ -1,20 +0,0 @@ -{% extends "musician/base.html" %} -{% load bootstrap4 i18n %} - -{% block content %} -

{{ service.verbose_name }}

- -
- {% csrf_token %} - {% bootstrap_form form %} - {% buttons %} - {% trans "Cancel" %} - - {% if form.instance %} - - {% endif %} - {% endbuttons %} -
-{% endblock %} diff --git a/idhub/templates/templates/musician/addresses.html b/idhub/templates/templates/musician/addresses.html deleted file mode 100644 index 1ebc8b7..0000000 --- a/idhub/templates/templates/musician/addresses.html +++ /dev/null @@ -1,41 +0,0 @@ -{% extends "musician/mail_base.html" %} -{% load i18n %} - -{% block tabcontent %} -
- - - - - - - - - - - - - - - - - {% for obj in object_list %} - - - - - - - {% endfor %} - - {% include "musician/components/table_paginator.html" %} -
{% trans "Email" %}{% trans "Domain" %}{% trans "Mailboxes" %}{% trans "Forward" %}
{{ obj.full_address_name }}{{ obj.domain.name }} - {% for mailbox in obj.mailboxes %} - {{ mailbox.name }} - {% if not forloop.last %}
{% endif %} - {% endfor %} -
{{ obj.forward }}
- {% trans "New mail address" %} - -
-{% endblock %} diff --git a/idhub/templates/templates/musician/billing.html b/idhub/templates/templates/musician/billing.html deleted file mode 100644 index 75f2580..0000000 --- a/idhub/templates/templates/musician/billing.html +++ /dev/null @@ -1,41 +0,0 @@ -{% extends "musician/base.html" %} -{% load i18n l10n %} - -{% block content %} - -

{% trans "Billing" %}

-

{% trans "Billing page description." %}

- - - - - - - - - - - - - - - - - - - - {% for bill in object_list %} - - - - - - - - {% endfor %} - -{# TODO: define proper colspan #} -{% include "musician/components/table_paginator.html" %} -
{% trans "Number" %}{% trans "Bill date" %}{% trans "Type" %}{% trans "Total" %}{% trans "Download PDF" %}
{{ bill.number }}{{ bill.created_on|date:"SHORT_DATE_FORMAT" }}{{ bill.type }}{{ bill.total|floatformat:2|localize }}€
- -{% endblock %} diff --git a/idhub/templates/templates/musician/components/paginator.html b/idhub/templates/templates/musician/components/paginator.html deleted file mode 100644 index 9a7a406..0000000 --- a/idhub/templates/templates/musician/components/paginator.html +++ /dev/null @@ -1,29 +0,0 @@ -{# #} -
-
{{ page_obj.paginator.count }} items in total
-
- {% if page_obj.has_previous %} - « - - {% endif %} - Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }} - {% if page_obj.has_next %} - - » - {% endif %} -
-
-
- Showing - - per page - -
-
-
diff --git a/idhub/templates/templates/musician/components/table_paginator.html b/idhub/templates/templates/musician/components/table_paginator.html deleted file mode 100644 index 913d5ae..0000000 --- a/idhub/templates/templates/musician/components/table_paginator.html +++ /dev/null @@ -1,50 +0,0 @@ -{# #} -{% load i18n %} - - - - {{ page_obj.paginator.count }} items in total - - - - -
- Showing - - per page - -
- - - diff --git a/idhub/templates/templates/musician/components/usage_progress_bar.html b/idhub/templates/templates/musician/components/usage_progress_bar.html deleted file mode 100644 index b35e84c..0000000 --- a/idhub/templates/templates/musician/components/usage_progress_bar.html +++ /dev/null @@ -1,22 +0,0 @@ -{% comment %} -Resource usage rendered as bootstrap progress bar - -Expected parameter: detail -Expected structure: dictionary or object with attributes: - - usage (int): 125 - - total (int): 200 - - unit (string): 'MB' - - percent (int: [0, 25, 50, 75, 100]: 75 -{% endcomment %} - -
- {% if detail %} - {{ detail.usage }} {{ detail.unit }} - {% else %} - N/A - {% endif %} -
-
-
-
diff --git a/idhub/templates/templates/musician/dashboard.html b/idhub/templates/templates/musician/dashboard.html deleted file mode 100644 index d359fcb..0000000 --- a/idhub/templates/templates/musician/dashboard.html +++ /dev/null @@ -1,161 +0,0 @@ -{% extends "musician/base.html" %} -{% load i18n %} - -{% block content %} - -

{% trans "Welcome back" %} {{ profile.username }}

-{% if profile.last_login %} -

{% blocktrans with last_login=profile.last_login|date:"SHORT_DATE_FORMAT" %}Last time you logged in was: {{ last_login }}{% endblocktrans %}

-{% else %} -

{% trans "It's the first time you log into the system, welcome on board!" %}

-{% endif %} - -
- {% for resource, usage in resource_usage.items %} -
-
-
{{ usage.verbose_name }}
- {% include "musician/components/usage_progress_bar.html" with detail=usage.data %} - {% if usage.data.alert %} -
- {{ usage.data.alert }} -
- {% endif %} -
-
- {% endfor %} -
-
-
{% trans "Notifications" %}
- {% for message in notifications %} -

{{ message }}

- {% empty %} -

{% trans "There is no notifications at this time." %}

- {% endfor %} -
-
-
- - -

{% trans "Your domains and websites" %}

-

{% trans "Dashboard page description." %}

- -{% for domain in domains %} -
-
-
-
- {{ domain.name }} -
-
- {% with domain.websites.0 as website %} - {% with website.contents.0 as content %} - - {% endwith %} - {% endwith %} -
-
- {% comment "@slamora: orchestra doesn't have this information [won't fix] See issue #2" %} - {% trans "Expiration date" %}: {{ domain.expiration_date|date:"SHORT_DATE_FORMAT" }} - {% endcomment %} -
-
-
-
-
-

{% trans "Mail" %}

-

-

- {{ domain.addresses|length }} {% trans "mail addresses created" %} -

- -
-
-

{% trans "Mail list" %}

-

- -
-
-

{% trans "Software as a Service" %}

-

-

{% trans "Nothing installed" %}

- -
-
-
-

{% trans "Disk usage" %}

-

-
- {% include "musician/components/usage_progress_bar.html" with detail=domain.usage %} -
-
-
-
-
- -{% endfor %} - - - -{% endblock %} -{% block extrascript %} - -{% endblock %} diff --git a/idhub/templates/templates/musician/databases.html b/idhub/templates/templates/musician/databases.html deleted file mode 100644 index cf71d1f..0000000 --- a/idhub/templates/templates/musician/databases.html +++ /dev/null @@ -1,68 +0,0 @@ -{% extends "musician/base.html" %} -{% load i18n %} - -{% block content %} - -

{{ service.verbose_name }}

-

{{ service.description }}

- -{% for database in object_list %} -
-
-
-
- {{ database.name }} -
-
- {% trans "Type" %}: {{ database.type }} -
-
- {% comment "@slamora: orchestra doesn't provide this information [won't fix] See issue #3" %} - {% trans "associated to" %}: {{ database.domain|default:"-" }} - {% endcomment %} -
-
-
-
-
-

Database users

-
    - {% for user in database.users %} - {# TODO(@slamora) render in two columns #} -
  • {{ user.username }}
  • - {% empty %} -
  • {% trans "No users for this database." %}
  • - {% endfor %} -
-
-
-

Database usage

-

- {% include "musician/components/usage_progress_bar.html" with detail=database.usage %} -
- -
-
- -{% empty %} -
-
-
-
-

- {# Translators: database page when there isn't any database. #} -
{% trans "Ooops! Looks like there is nothing here!" %}
-
-
-
-
-{% endfor %} - - {% if object_list|length > 0 %} - {% include "musician/components/paginator.html" %} - {% endif %} -{% endblock %} diff --git a/idhub/templates/templates/musician/domain_detail.html b/idhub/templates/templates/musician/domain_detail.html deleted file mode 100644 index 761c331..0000000 --- a/idhub/templates/templates/musician/domain_detail.html +++ /dev/null @@ -1,30 +0,0 @@ -{% extends "musician/base.html" %} -{% load i18n %} - -{% block content %} -{% trans "Go back" %} - -

{% trans "DNS settings for" %} {{ object.name }}

-

{% trans "DNS settings page description." %}

- - - - - - - - - - - - - - {% for record in object.records %} - - - - - {% endfor %} - -
{% trans "Type" %}{% trans "Value" %}
{{ record.type }}{{ record.value }}
-{% endblock %} diff --git a/idhub/templates/templates/musician/mail_base.html b/idhub/templates/templates/musician/mail_base.html deleted file mode 100644 index 9445f7f..0000000 --- a/idhub/templates/templates/musician/mail_base.html +++ /dev/null @@ -1,32 +0,0 @@ -{% extends "musician/base.html" %} -{% load i18n %} - -{% block content %} -{% if active_domain %} -{% trans "Go to global" %} -{% endif %} - -

{{ service.verbose_name }} - {% if active_domain %}{% trans "for" %} {{ active_domain.name }}{% endif %} -

-

{{ service.description }}

- -{% with request.resolver_match.url_name as url_name %} - - -{% endwith %} - -
- {% block tabcontent %} - {% endblock %} - -{% endblock %} diff --git a/idhub/templates/templates/musician/mailbox_change_password.html b/idhub/templates/templates/musician/mailbox_change_password.html deleted file mode 100644 index e18b95a..0000000 --- a/idhub/templates/templates/musician/mailbox_change_password.html +++ /dev/null @@ -1,15 +0,0 @@ -{% extends "musician/base.html" %} -{% load bootstrap4 i18n %} - -{% block content %} -

{% trans "Change password" %}: {{ object.name }}

- -
- {% csrf_token %} - {% bootstrap_form form %} - {% buttons %} - {% trans "Cancel" %} - - {% endbuttons %} -
-{% endblock %} diff --git a/idhub/templates/templates/musician/mailbox_check_delete.html b/idhub/templates/templates/musician/mailbox_check_delete.html deleted file mode 100644 index 18b9249..0000000 --- a/idhub/templates/templates/musician/mailbox_check_delete.html +++ /dev/null @@ -1,15 +0,0 @@ -{% extends "musician/base.html" %} -{% load i18n %} - -{% block content %} -
- {% csrf_token %} -

{% blocktrans with name=object.name %}Are you sure that you want remove the mailbox: "{{ name }}"?{% endblocktrans %}

- -

{% trans 'WARNING: This action cannot be undone.' %}

- - {% trans 'Cancel' %} -
-{% endblock %} diff --git a/idhub/templates/templates/musician/mailbox_form.html b/idhub/templates/templates/musician/mailbox_form.html deleted file mode 100644 index 5fb9465..0000000 --- a/idhub/templates/templates/musician/mailbox_form.html +++ /dev/null @@ -1,30 +0,0 @@ -{% extends "musician/base.html" %} -{% load bootstrap4 i18n %} - -{% block content %} -

{{ service.verbose_name }}

- -{% if extra_mailbox %} - -{% endif %} - -
- {% csrf_token %} - {% bootstrap_form form %} - {% buttons %} - {% trans "Cancel" %} - - {% if form.instance %} - - {% endif %} - {% endbuttons %} -
-{% endblock %} diff --git a/idhub/templates/templates/musician/mailboxes.html b/idhub/templates/templates/musician/mailboxes.html deleted file mode 100644 index a9f3700..0000000 --- a/idhub/templates/templates/musician/mailboxes.html +++ /dev/null @@ -1,46 +0,0 @@ -{% extends "musician/mail_base.html" %} -{% load i18n %} - -{% block tabcontent %} -
- - - - - - - - - - - - - - - {% for mailbox in object_list %} - {# #} - {% if mailbox.is_active %} - - - - - - {% endif %}{# #} - {% endfor %} - - {% include "musician/components/table_paginator.html" %} -
{% trans "Name" %}{% trans "Filtering" %}{% trans "Addresses" %}
- {{ mailbox.name }} - - {% trans "Update password" %} - {{ mailbox.filtering }} - {% for addr in mailbox.addresses %} - - {{ addr.full_address_name }} -
- {% endfor %} -
- {% trans "New mailbox" %} - -
-{% endblock %} diff --git a/idhub/templates/templates/musician/mailinglists.html b/idhub/templates/templates/musician/mailinglists.html deleted file mode 100644 index 6ff509e..0000000 --- a/idhub/templates/templates/musician/mailinglists.html +++ /dev/null @@ -1,46 +0,0 @@ -{% extends "musician/base.html" %} -{% load i18n %} - -{% block content %} -{% if active_domain %} -{% trans "Go to global" %} -{% endif %} - -

{{ service.verbose_name }}{% if active_domain %} {% trans "for" %} {{ active_domain.name }}{% endif %}

-

{{ service.description }}

- - - - - - - - - - - - - - - - - - - - {% for resource in object_list %} - - - {% if resource.is_active %} - - {% else %} - - {% endif %} - - - - - {% endfor %} - - {% include "musician/components/table_paginator.html" %} -
NameStatusAddressAdmin emailConfigure
{{ resource.name }}{% trans "Active" %}{% trans "Inactive" %}{{ resource.address_name}}{{ resource.admin_email }}Mailtrain
-{% endblock %} diff --git a/idhub/templates/templates/musician/profile.html b/idhub/templates/templates/musician/profile.html deleted file mode 100644 index f6bdbce..0000000 --- a/idhub/templates/templates/musician/profile.html +++ /dev/null @@ -1,65 +0,0 @@ -{% extends "musician/base.html" %} -{% load i18n %} - -{% block content %} - -

{% trans "Profile" %}

-

{% trans "Little description on profile page." %}

- -
-
-
{% trans "User information" %}
-
-
-
- user-profile-picture -
-
-
-

{{ profile.username }}

-

{{ profile.type }}

-

{% trans "Preferred language:" %} {{ profile.language|language_name_local }}

-
- {% comment %} - - - {% endcomment %} -
-
- - {% with profile.billing as contact %} -
-
{% trans "Billing information" %}
-
-
{{ contact.name }}
-
{{ contact.address }}
-
- {{ contact.zipcode }} - {{ contact.city }} - {{ contact.country }} -
-
- {{ contact.vat }} -
- -
- {% trans "payment method:" %} {{ payment.method }} -
-
- {% if payment.method == 'SEPADirectDebit' %} - IBAN {{ payment.data.iban }} - {% else %} - {# #} - Details: {{ payment.data }} - {% endif %} -
- -
-
-
-{% endwith %} -{% endblock %} diff --git a/idhub/templates/templates/musician/saas.html b/idhub/templates/templates/musician/saas.html deleted file mode 100644 index 4da034f..0000000 --- a/idhub/templates/templates/musician/saas.html +++ /dev/null @@ -1,56 +0,0 @@ -{% extends "musician/base.html" %} -{% load i18n %} - -{% block content %} - -

{{ service.verbose_name }}

-

{{ service.description }}

- -{% for saas in object_list %} -
-
-
-
- {{ saas.name }} -
- {% comment "Hidden until API provides this information" %} -
- {% trans "Installed on" %}: {{ saas.domain|default:"-" }} -
- {% endcomment %} -
-
-
-
-

{{ saas.service|capfirst }}

-

-
-
-

{% trans "Service info" %}

- {{ saas.is_active|yesno }}
- {% for key, value in saas.data.items %} - {{ value }}
- {% endfor %} -
- -
-
- {% empty %} -
-
-
-
-

- {# Translators: saas page when there isn't any saas. #} -
{% trans "Ooops! Looks like there is nothing here!" %}
-
-
-
-
-{% endfor %} - -{% endblock %} diff --git a/idhub/templates/templates/musician/service_list.html b/idhub/templates/templates/musician/service_list.html deleted file mode 100644 index d413fc8..0000000 --- a/idhub/templates/templates/musician/service_list.html +++ /dev/null @@ -1,28 +0,0 @@ -{% extends "musician/base.html" %} -{% load i18n musician %} - -{% block content %} - -

{{ service.verbose_name }}

-

{{ service.description }}

- - - - - {% for field_name in service.fields %} - - {% endfor %} - - - - {% for resource in object_list %} - - {% for field_name in service.fields %} - - {% endfor %} - - {% endfor %} - - {% include "musician/components/table_paginator.html" %} -
{{ field_name }}
{{ resource|get_item:field_name }}
-{% endblock %}