diff --git a/.gitea/workflows/ci-pipeline.yaml b/.gitea/workflows/ci-pipeline.yaml index f7d4633..02ba211 100644 --- a/.gitea/workflows/ci-pipeline.yaml +++ b/.gitea/workflows/ci-pipeline.yaml @@ -50,7 +50,7 @@ jobs: - name: Get DIDKit wheel id: didkit run: | - wget https://gitea.pangea.org/trustchain-oc1-orchestral/ssikit_trustchain/raw/branch/master/didkit-0.3.2-cp311-cp311-manylinux_2_34_x86_64.whl + wget -O didkit-0.3.2-cp311-cp311-manylinux_2_34_x86_64.whl https://gitea.pangea.org/api/v1/repos/trustchain-oc1-orchestral/ssikit_trustchain/raw/didkit-0.3.2-cp311-cp311-manylinux_2_34_x86_64.whl?token=${{ secrets.FILE_GETTER_TOKEN }} echo "Successfully downloaded DIDkit" - name: Install dependencies @@ -69,3 +69,21 @@ jobs: source venv/bin/activate python manage.py test + + deploy: + needs: test + runs-on: self-hosted + steps: + - uses: actions/checkout@v4 + + - name: Trigger Remote Script + run: | + response=$(curl -s -o /dev/null -w "%{http_code}" -X POST http://45.150.187.54:5000/trigger-script -H "Authorization: SecretToken") + if [ "$response" -ne 200 ]; then + echo "Script execution failed with HTTP status $response" + exit 1 + else + echo "Script execution successful" + exit 0 + fi + if: success() && github.ref == 'refs/heads/main' diff --git a/examples/excel_templates/course-credential.xlsx b/examples/excel_templates/course-credential.xlsx new file mode 100644 index 0000000..05cc159 Binary files /dev/null and b/examples/excel_templates/course-credential.xlsx differ diff --git a/examples/excel_templates/device-purchase.xlsx b/examples/excel_templates/device-purchase.xlsx new file mode 100644 index 0000000..0a0a924 Binary files /dev/null and b/examples/excel_templates/device-purchase.xlsx differ diff --git a/examples/excel_templates/e-operator-claim.xlsx b/examples/excel_templates/e-operator-claim.xlsx new file mode 100644 index 0000000..f8f886e Binary files /dev/null and b/examples/excel_templates/e-operator-claim.xlsx differ diff --git a/examples/excel_templates/federation-membership.xlsx b/examples/excel_templates/federation-membership.xlsx new file mode 100644 index 0000000..3d20590 Binary files /dev/null and b/examples/excel_templates/federation-membership.xlsx differ diff --git a/examples/excel_templates/financial-vulnerability.xlsx b/examples/excel_templates/financial-vulnerability.xlsx new file mode 100644 index 0000000..012929f Binary files /dev/null and b/examples/excel_templates/financial-vulnerability.xlsx differ diff --git a/examples/excel_templates/membership-card.xlsx b/examples/excel_templates/membership-card.xlsx new file mode 100644 index 0000000..c075579 Binary files /dev/null and b/examples/excel_templates/membership-card.xlsx differ diff --git a/examples/financial-vulnerability.xlsx b/examples/financial-vulnerability.xlsx new file mode 100644 index 0000000..eb016f3 Binary files /dev/null and b/examples/financial-vulnerability.xlsx differ diff --git a/idhub/admin/forms.py b/idhub/admin/forms.py index 5476507..59d0eb3 100644 --- a/idhub/admin/forms.py +++ b/idhub/admin/forms.py @@ -23,7 +23,7 @@ from idhub.models import ( from idhub_auth.models import User -class TermsConditionsForm(forms.Form): +class TermsConditionsForm2(forms.Form): accept = forms.BooleanField( label=_("Accept terms and conditions of the service"), required=False @@ -50,6 +50,65 @@ class TermsConditionsForm(forms.Form): return +class TermsConditionsForm(forms.Form): + accept_privacy = forms.BooleanField( + widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}), + required=False + ) + accept_legal = forms.BooleanField( + widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}), + required=False + ) + accept_cookies = forms.BooleanField( + widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}), + required=False + ) + + def __init__(self, *args, **kwargs): + self.user = kwargs.pop('user', None) + super().__init__(*args, **kwargs) + + def get_label(self, url, read): + label = _('I read and accepted the') + label += f' {read}' + return label + + def privacy_label(self): + url = "https://laweb.pangea.org/politica-de-privacitat/" + read = _("Privacy policy") + return self.get_label(url, read) + + def legal_label(self): + url = "https://laweb.pangea.org/avis-legal/" + read = _("Legal policy") + return self.get_label(url, read) + + def cookies_label(self): + url = "https://laweb.pangea.org/politica-de-cookies-2/" + read = _("Cookies policy") + return self.get_label(url, read) + + def clean(self): + data = self.cleaned_data + privacy = data.get("accept_privacy") + legal = data.get("accept_legal") + cookies = data.get("accept_cookies") + if privacy and legal and cookies: + 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=[]) eidas1 = forms.ChoiceField( @@ -189,7 +248,7 @@ class ImportForm(forms.Form): cred = VerificableCredential( verified=False, user=user, - csv_data=json.dumps(row), + csv_data=json.dumps(row, default=str), issuer_did=self._did, schema=self._schema, eidas1_did=self._eidas1 diff --git a/idhub/admin/views.py b/idhub/admin/views.py index 3773cab..25ac28d 100644 --- a/idhub/admin/views.py +++ b/idhub/admin/views.py @@ -25,7 +25,7 @@ from django.contrib import messages from utils import credtools from idhub_auth.models import User from idhub_auth.forms import ProfileForm -from idhub.mixins import AdminView +from idhub.mixins import AdminView, Http403 from idhub.email.views import NotifyActivateUserByEmail from idhub.admin.forms import ( ImportForm, @@ -60,9 +60,9 @@ from idhub.models import ( class TermsAndConditionsView(AdminView, FormView): template_name = "idhub/admin/terms_conditions.html" - title = _("GDPR") + title = _('Data protection') section = "" - subtitle = _('Accept Terms and Conditions') + subtitle = _('Terms and Conditions') icon = 'bi bi-file-earmark-medical' form_class = TermsConditionsForm success_url = reverse_lazy('idhub:admin_dashboard') @@ -70,7 +70,12 @@ class TermsAndConditionsView(AdminView, FormView): def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs['user'] = self.request.user - kwargs['initial'] = {"accept": self.request.user.accept_gdpr} + if self.request.user.accept_gdpr: + kwargs['initial'] = { + "accept_privacy": True, + "accept_legal": True, + "accept_cookies": True + } return kwargs def form_valid(self, form): @@ -82,7 +87,9 @@ class DobleFactorAuthView(AdminView, View): url = reverse_lazy('idhub:admin_dashboard') def get(self, request, *args, **kwargs): - self.check_valid_user() + if not self.request.user.is_admin: + raise Http403() + if not self.request.session.get("2fauth"): return redirect(self.url) @@ -700,12 +707,13 @@ class DidsView(Credentials, SingleTableView): def get_context_data(self, **kwargs): queryset = kwargs.pop('object_list', None) + dids = DID.objects.filter(user=self.request.user) if queryset is None: - self.object_list = self.model.objects.all() + self.object_list = dids.all() context = super().get_context_data(**kwargs) context.update({ - 'dids': DID.objects.filter(user=self.request.user), + 'dids': dids }) return context @@ -905,19 +913,20 @@ class SchemasImportAddView(SchemasMix): def get(self, request, *args, **kwargs): self.check_valid_user() - file_name = kwargs['file_schema'] + self.file_name = kwargs['file_schema'] schemas_files = os.listdir(settings.SCHEMAS_DIR) - if file_name not in schemas_files: + if self.file_name not in schemas_files: + file_name = self.file_name messages.error(self.request, f"The schema {file_name} not exist!") return redirect('idhub:admin_schemas_import') - schema = self.create_schema(file_name) + schema = self.create_schema() if schema: messages.success(self.request, _("The schema was added sucessfully")) return redirect('idhub:admin_schemas') - def create_schema(self, file_name): - data = self.open_file(file_name) + def create_schema(self): + data = self.open_file() try: ldata = json.loads(data) assert credtools.validate_schema(ldata) @@ -933,7 +942,7 @@ class SchemasImportAddView(SchemasMix): _description = json.dumps(ldata.get('description', '')) schema = Schemas.objects.create( - file_schema=file_name, + file_schema=self.file_name, data=data, type=title, _name=_name, @@ -944,9 +953,9 @@ class SchemasImportAddView(SchemasMix): schema.save() return schema - def open_file(self, file_name): + def open_file(self): data = '' - filename = Path(settings.SCHEMAS_DIR).joinpath(file_name) + filename = Path(settings.SCHEMAS_DIR).joinpath(self.file_name) with filename.open() as schema_file: data = schema_file.read() @@ -955,7 +964,7 @@ class SchemasImportAddView(SchemasMix): def get_template_description(self): context = {} template_name = 'credentials/{}'.format( - self.schema.file_schema + self.file_name ) tmpl = get_template(template_name) return tmpl.render(context) @@ -970,7 +979,7 @@ class SchemasImportAddView(SchemasMix): class ImportView(ImportExport, SingleTableView): template_name = "idhub/admin/import.html" table_class = DataTable - subtitle = _('Import data') + subtitle = _('Imported data') icon = '' model = File_datas diff --git a/idhub/email/views.py b/idhub/email/views.py index f14e2a5..caa9370 100644 --- a/idhub/email/views.py +++ b/idhub/email/views.py @@ -57,12 +57,13 @@ class NotifyActivateUserByEmail: html_email = loader.render_to_string(self.html_email_template_name, context) email_message.attach_alternative(html_email, 'text/html') try: - if settings.DEVELOPMENT: - logger.warning(to_email) - logger.warning(body) + if settings.ENABLE_EMAIL: + email_message.send() return - email_message.send() + logger.warning(to_email) + logger.warning(body) + except Exception as err: logger.error(err) return diff --git a/idhub/management/commands/initial_datas.py b/idhub/management/commands/initial_datas.py index 69c1ef5..00224d9 100644 --- a/idhub/management/commands/initial_datas.py +++ b/idhub/management/commands/initial_datas.py @@ -23,11 +23,12 @@ class Command(BaseCommand): def handle(self, *args, **kwargs): ADMIN_EMAIL = config('ADMIN_EMAIL', 'admin@example.org') ADMIN_PASSWORD = config('ADMIN_PASSWORD', '1234') - USER_EMAIL = config('USER_EMAIL', 'user1@example.org') - USER_PASSWORD = config('USER_PASSWORD', '1234') self.create_admin_users(ADMIN_EMAIL, ADMIN_PASSWORD) - self.create_users(USER_EMAIL, USER_PASSWORD) + if settings.CREATE_TEST_USERS: + for u in range(1, 6): + user = 'user{}@example.org'.format(u) + self.create_users(user, '1234') BASE_DIR = Path(__file__).resolve().parent.parent.parent.parent ORGANIZATION = os.path.join(BASE_DIR, settings.ORG_FILE) diff --git a/idhub/models.py b/idhub/models.py index fea0156..c1feadd 100644 --- a/idhub/models.py +++ b/idhub/models.py @@ -674,7 +674,6 @@ class VerificableCredential(models.Model): 'organisation': settings.ORGANIZATION or '', } context.update(d) - context['firstName'] = "" return context def render(self, domain): diff --git a/idhub/templates/auth/2fadmin.html b/idhub/templates/auth/2fadmin.html index 4dc2ae6..e96d1b7 100644 --- a/idhub/templates/auth/2fadmin.html +++ b/idhub/templates/auth/2fadmin.html @@ -5,14 +5,14 @@
-

{% trans 'Doble Factor of Authentication' %}

+

{% trans 'Two-factor Authentication' %}

- {% trans "We have sent an email with a link that you have to select in order to login." %} + {% trans "We have sent you an email with a link that you have to click to log in." %}
diff --git a/idhub/templates/auth/2fadmin_email.html b/idhub/templates/auth/2fadmin_email.html index d2253c5..6ea0793 100644 --- a/idhub/templates/auth/2fadmin_email.html +++ b/idhub/templates/auth/2fadmin_email.html @@ -1,6 +1,6 @@ {% load i18n %}{% autoescape off %}

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

diff --git a/idhub/templates/auth/2fadmin_email.txt b/idhub/templates/auth/2fadmin_email.txt index a9ef3e5..6328f66 100644 --- a/idhub/templates/auth/2fadmin_email.txt +++ b/idhub/templates/auth/2fadmin_email.txt @@ -1,5 +1,5 @@ {% load i18n %}{% autoescape off %} -{% blocktrans %}You're receiving this email because you try to access in {{ site_name }}.{% endblocktrans %} +{% blocktrans %}You're receiving this email because you tried to access {{ site_name }}.{% endblocktrans %} {% trans "Please go to the following page" %} {% block reset_link %} diff --git a/idhub/templates/auth/login.html b/idhub/templates/auth/login.html index 18abfd8..1a1775c 100644 --- a/idhub/templates/auth/login.html +++ b/idhub/templates/auth/login.html @@ -46,7 +46,7 @@ class="btn btn-primary form-control" id="submit-id-submit"> -

{% endif %} -
+ +
- You must read the terms and conditions of this service and accept the - Read GDPR + {{ form.accept_privacy }} + {{ form.privacy_label|safe }}
-
-
- {% bootstrap_form form %} +
+
+ {{ form.accept_legal }} + {{ form.legal_label|safe }}
-
- {% translate "Cancel" %} - +
+
+ {{ form.accept_cookies }} + {{ form.cookies_label|safe }} +
+
+ - + +{% endblock %} + +{% block extrascript %} + {% endblock %} diff --git a/idhub/templates/idhub/base.html b/idhub/templates/idhub/base.html index e579a81..46dee02 100644 --- a/idhub/templates/idhub/base.html +++ b/idhub/templates/idhub/base.html @@ -87,8 +87,8 @@ @@ -150,9 +150,12 @@
+ {% block script %} + - + {% block extrascript %}{% endblock %} + {% endblock %} diff --git a/idhub/templates/idhub/user/profile.html b/idhub/templates/idhub/user/profile.html index 6efdc48..cfbc4b9 100644 --- a/idhub/templates/idhub/user/profile.html +++ b/idhub/templates/idhub/user/profile.html @@ -11,7 +11,12 @@
- {% trans 'ARCO Forms' %} + {% if lang == 'es' %} + {% trans 'ARCO Forms' %} + {% else %} + {% trans 'ARCO Forms' %} + {% endif %} + {% trans 'Notice of Privacy' %}
diff --git a/idhub/templates/idhub/user/terms_conditions.html b/idhub/templates/idhub/user/terms_conditions.html index 8a02175..4175a60 100644 --- a/idhub/templates/idhub/user/terms_conditions.html +++ b/idhub/templates/idhub/user/terms_conditions.html @@ -20,38 +20,68 @@ {% endif %} -
+
- You must read the terms and conditions of this service and accept the - Read GDPR + {{ form.accept_privacy }} + {{ form.privacy_label|safe }}
-
-
- {% bootstrap_form form %} +
+
+ {{ form.accept_legal }} + {{ form.legal_label|safe }}
-
- {% translate "Cancel" %} - +
+
+ {{ form.accept_cookies }} + {{ form.cookies_label|safe }} +
+
+ - + +{% endblock %} + +{% block extrascript %} + {% endblock %} diff --git a/idhub/urls.py b/idhub/urls.py index d107b3f..30338b3 100644 --- a/idhub/urls.py +++ b/idhub/urls.py @@ -19,6 +19,7 @@ from django.views.generic import RedirectView from django.urls import path, reverse_lazy from .views import ( LoginView, + PasswordResetView, PasswordResetConfirmView, serve_did, DobleFactorSendView, @@ -34,16 +35,7 @@ urlpatterns = [ permanent=False)), path('login/', LoginView.as_view(), name='login'), path('logout/', auth_views.LogoutView.as_view(), name='logout'), - path('auth/password_reset/', - auth_views.PasswordResetView.as_view( - template_name='auth/password_reset.html', - email_template_name='auth/password_reset_email.txt', - html_email_template_name='auth/password_reset_email.html', - subject_template_name='auth/password_reset_subject.txt', - success_url=reverse_lazy('idhub:password_reset_done') - ), - name='password_reset' - ), + path('auth/password_reset/', PasswordResetView.as_view(), name='password_reset'), path('auth/password_reset/done/', auth_views.PasswordResetDoneView.as_view( template_name='auth/password_reset_done.html' @@ -53,13 +45,6 @@ urlpatterns = [ path('auth/reset///', PasswordResetConfirmView.as_view(), name='password_reset_confirm' ), - # path('auth/reset///', - # auth_views.PasswordResetConfirmView.as_view( - # template_name='auth/password_reset_confirm.html', - # success_url=reverse_lazy('idhub:password_reset_complete') - # ), - # name='password_reset_confirm' - # ), path('auth/reset/done/', auth_views.PasswordResetCompleteView.as_view( template_name='auth/password_reset_complete.html' diff --git a/idhub/user/forms.py b/idhub/user/forms.py index bad06be..9561eb7 100644 --- a/idhub/user/forms.py +++ b/idhub/user/forms.py @@ -15,8 +15,16 @@ class ProfileForm(forms.ModelForm): class TermsConditionsForm(forms.Form): - accept = forms.BooleanField( - label=_("Accept terms and conditions of the service"), + accept_privacy = forms.BooleanField( + widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}), + required=False + ) + accept_legal = forms.BooleanField( + widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}), + required=False + ) + accept_cookies = forms.BooleanField( + widget=forms.CheckboxInput(attrs={'class': 'form-check-input'}), required=False ) @@ -24,9 +32,33 @@ class TermsConditionsForm(forms.Form): self.user = kwargs.pop('user', None) super().__init__(*args, **kwargs) + def get_label(self, url, read): + label = _('I read and accepted the') + label += f' {read}' + return label + + def privacy_label(self): + url = "https://laweb.pangea.org/politica-de-privacitat/" + read = _("Privacy policy") + return self.get_label(url, read) + + def legal_label(self): + url = "https://laweb.pangea.org/avis-legal/" + read = _("Legal policy") + return self.get_label(url, read) + + def cookies_label(self): + url = "https://laweb.pangea.org/politica-de-cookies-2/" + read = _("Cookies policy") + return self.get_label(url, read) + def clean(self): data = self.cleaned_data - if data.get("accept"): + privacy = data.get("accept_privacy") + legal = data.get("accept_legal") + cookies = data.get("accept_cookies") + if privacy and legal and cookies: self.user.accept_gdpr = True else: self.user.accept_gdpr = False diff --git a/idhub/user/tables.py b/idhub/user/tables.py index 28045e9..eacdcb8 100644 --- a/idhub/user/tables.py +++ b/idhub/user/tables.py @@ -117,6 +117,13 @@ class DIDTable(tables.Table): class CredentialsTable(tables.Table): description = tables.Column(verbose_name="Details", empty_values=()) + view_credential = ButtonColumn( + linkify={ + "viewname": "idhub:user_credential", + "args": [tables.A("pk")] + }, + orderable=False + ) def render_description(self, record): return record.get_description() @@ -131,6 +138,9 @@ class CredentialsTable(tables.Table): return (queryset, True) + def render_view_credential(self): + return format_html('') + class Meta: model = VerificableCredential template_name = "idhub/custom_table.html" diff --git a/idhub/user/views.py b/idhub/user/views.py index 82c5337..27c8f77 100644 --- a/idhub/user/views.py +++ b/idhub/user/views.py @@ -100,6 +100,13 @@ class ProfileView(MyProfile, UpdateView, SingleTableView): def form_valid(self, form): return super().form_valid(form) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context.update({ + 'lang': self.request.LANGUAGE_CODE, + }) + return context class RolesView(MyProfile, SingleTableView): @@ -116,7 +123,7 @@ class RolesView(MyProfile, SingleTableView): class GDPRView(MyProfile, TemplateView): template_name = "idhub/user/gdpr.html" - subtitle = _('GDPR info') + subtitle = _('Data protection') icon = 'bi bi-file-earmark-medical' @@ -135,9 +142,9 @@ class CredentialsView(MyWallet, SingleTableView): class TermsAndConditionsView(UserView, FormView): template_name = "idhub/user/terms_conditions.html" - title = _("GDPR") + title = _("Data Protection") section = "" - subtitle = _('Accept Terms and Conditions') + subtitle = _('Terms and Conditions') icon = 'bi bi-file-earmark-medical' form_class = TermsConditionsForm success_url = reverse_lazy('idhub:user_dashboard') @@ -145,7 +152,12 @@ class TermsAndConditionsView(UserView, FormView): def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs['user'] = self.request.user - kwargs['initial'] = {"accept": self.request.user.accept_gdpr} + if self.request.user.accept_gdpr: + kwargs['initial'] = { + "accept_privacy": True, + "accept_legal": True, + "accept_cookies": True + } return kwargs def form_valid(self, form): diff --git a/idhub/views.py b/idhub/views.py index 9c2d595..06aeed0 100644 --- a/idhub/views.py +++ b/idhub/views.py @@ -1,4 +1,5 @@ import uuid +import logging from django.conf import settings from django.core.cache import cache @@ -16,6 +17,9 @@ from idhub.email.views import NotifyActivateUserByEmail from trustchain_idhub import settings +logger = logging.getLogger(__name__) + + class LoginView(auth_views.LoginView): template_name = 'auth/login.html' extra_context = { @@ -52,7 +56,7 @@ class LoginView(auth_views.LoginView): # ) # cache.set("KEY_DIDS", encryption_key, None) cache.set("KEY_DIDS", sensitive_data_encryption_key, None) - if not settings.DEVELOPMENT: + if settings.ENABLE_2FACTOR_AUTH: self.request.session["2fauth"] = str(uuid.uuid4()) return redirect(reverse_lazy('idhub:confirm_send_2f')) @@ -69,13 +73,31 @@ class PasswordResetConfirmView(auth_views.PasswordResetConfirmView): success_url = reverse_lazy('idhub:password_reset_complete') def form_valid(self, form): - password = form.cleaned_data.get("password") - user = form.get_user() + password = form.cleaned_data.get("new_password1") + user = form.user + user.set_password(password) user.set_encrypted_sensitive_data(password) user.save() return HttpResponseRedirect(self.success_url) +class PasswordResetView(auth_views.PasswordResetView): + template_name = 'auth/password_reset.html' + email_template_name = 'auth/password_reset_email.txt' + html_email_template_name = 'auth/password_reset_email.html' + subject_template_name = 'auth/password_reset_subject.txt' + success_url = reverse_lazy('idhub:password_reset_done') + + def form_valid(self, form): + try: + return super().form_valid(form) + except Exception as err: + logger.error(err) + # url_error = reverse_lazy('idhub:password_reset_error') + # return HttpResponseRedirect(url_error) + return HttpResponseRedirect(self.success_url) + + def serve_did(request, did_id): id_did = f'did:web:{settings.DOMAIN}:did-registry:{did_id}' did = get_object_or_404(DID, did=id_did) diff --git a/idhub_auth/models.py b/idhub_auth/models.py index e89bc35..ca4b422 100644 --- a/idhub_auth/models.py +++ b/idhub_auth/models.py @@ -155,3 +155,11 @@ class User(AbstractBaseUser): pw = base64.b64decode(password.encode('utf-8')*4) sb_key = self.derive_key_from_password(pw) return nacl.secret.SecretBox(sb_key) + + def change_password(self, old_password, new_password): + sensitive_data = self.decrypt_sensitive_data(old_password) + self.encrypted_sensitive_data = self.encrypt_sensitive_data( + new_password, + sensitive_data + ) + self.set_password(new_password) diff --git a/oidc4vp/views.py b/oidc4vp/views.py index d6eec81..7161aed 100644 --- a/oidc4vp/views.py +++ b/oidc4vp/views.py @@ -137,8 +137,7 @@ class VerifyView(View): vp_token.verifing() response = vp_token.get_response_verify() vp_token.save() - if not vp_token.authorization.promotions.exists(): - response["response"] = "Validation Code {}".format(code) + response["response"] = "Validation Code {}".format(code) return JsonResponse(response) diff --git a/promotion/forms.py b/promotion/forms.py index 5b96423..30dce87 100644 --- a/promotion/forms.py +++ b/promotion/forms.py @@ -14,7 +14,10 @@ from promotion.models import Promotion class WalletForm(forms.Form): - organization = forms.ChoiceField(choices=[]) + organization = forms.ChoiceField( + choices=[], + widget=forms.Select(attrs={'class': 'form-select'}) + ) def __init__(self, *args, **kwargs): self.presentation_definition = kwargs.pop('presentation_definition', []) diff --git a/promotion/templates/select_wallet.html b/promotion/templates/select_wallet.html index ba813ee..590fa7b 100644 --- a/promotion/templates/select_wallet.html +++ b/promotion/templates/select_wallet.html @@ -1,1126 +1,93 @@ - - - - - - - - - - - - +{% load i18n static %} + + + + + + + + + + {% block title %}{% if title %}{{ title }} – {% endif %}Pangea{% endblock %} + + + + + + + - - Escull la teva tarifa mòbil - Som Connexió - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
- - Tarifes
- -
-
-
- Persones sòcies 9.257 - Contractes 22.303 -
- -
- Blog  |  - Contacte -
- - - Vols que et truquem? -
-
-skip to Main Content
-
- - - - - - -
- -
- - -
- - -
- - - -
- - -{% load i18n %} -{% load django_bootstrap5 %} -
-{% csrf_token %} -{% if form.errors %} - -{% endif %} -
-
- {% bootstrap_form form %} -
-
- - -
-
- -
- - -
- - -
- - - -
- - - - - - - - - - -
- - -
- - - - -Back To Top - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -