diff --git a/examples/organizations__instance_localhost-pair.csv b/examples/organizations__instance_localhost-pair.csv new file mode 100644 index 0000000..9f283d2 --- /dev/null +++ b/examples/organizations__instance_localhost-pair.csv @@ -0,0 +1,2 @@ +"localhost idhub1";"http://localhost/oidc4vp/";"localhost" +"localhost idhub2";"http://idhub2/oidc4vp/";"idhub2" diff --git a/idhub/admin/forms.py b/idhub/admin/forms.py index 3796969..a8ac0fa 100644 --- a/idhub/admin/forms.py +++ b/idhub/admin/forms.py @@ -217,13 +217,13 @@ class ImportForm(forms.Form): return data def clean_file_import(self): - props = self.json_schema.get("properties", {}) data = self.cleaned_data["file_import"] - self.file_name = data.name - if not self._schema: return data + self.file_name = data.name + props = self.json_schema.get("properties", {}) + # Forze than pandas read one column as string dtype_dict = {"phoneNumber": str} df = pd.read_excel(data, dtype=dtype_dict) diff --git a/idhub/templates/idhub/admin/issue_credentials.html b/idhub/templates/idhub/admin/issue_credentials.html index 216690e..f046683 100644 --- a/idhub/templates/idhub/admin/issue_credentials.html +++ b/idhub/templates/idhub/admin/issue_credentials.html @@ -11,6 +11,7 @@
{% if object.get_status == 'Issued' %} + {% trans 'Download as JSON' %} {% trans 'Revoke' %} {% endif %} {% if object.get_status == 'Enabled' %} @@ -48,13 +49,6 @@ {{ object.get_status}}
- {% if object.issued_on %} -
-
- {% trans 'Download in JSON format' %} -
-
- {% endif %} diff --git a/idhub/templates/idhub/user/credential.html b/idhub/templates/idhub/user/credential.html index ac5c14e..9e1e0f4 100644 --- a/idhub/templates/idhub/user/credential.html +++ b/idhub/templates/idhub/user/credential.html @@ -2,10 +2,29 @@ {% load i18n %} {% block content %} -

- - {{ subtitle }} -

+
+
+

+ + {{ subtitle }} +

+
+
+ {% if object.get_status == 'Issued' %} +
+ {% if object.eidas1_did and admin_validated %} + {% trans 'Download as PDF' %} + {% endif %} + {% trans 'Download as JSON' %} +
+ {% endif %} + {% if object.get_status == 'Enabled' %} + + {% endif %} +
+
@@ -38,21 +57,5 @@
- {% if object.get_status == 'Issued' %} -
- {% if object.eidas1_did and admin_validated %} -
- {% trans 'Sign credential in PDF format' %} -
- {% endif %} -
- {% trans 'Download credential in JSON format' %} -
- {% endif %} - {% if object.get_status == 'Enabled' %} -
- {% trans 'Request credential' %} -
- {% endif %}
{% endblock %} diff --git a/idhub/templates/idhub/user/credentials_presentation.html b/idhub/templates/idhub/user/credentials_presentation.html index b94e3c8..59dd4f4 100644 --- a/idhub/templates/idhub/user/credentials_presentation.html +++ b/idhub/templates/idhub/user/credentials_presentation.html @@ -20,6 +20,7 @@ {% endif %} +{% if form.if_credentials %}
{% bootstrap_form form %} @@ -29,6 +30,13 @@ {% trans "Cancel" %}
+{% else %} +
+
+ {% trans 'Sorry no there are credentials to present' %} +
+
+{% endif %} {% endblock %} diff --git a/idhub/templates/idhub/user/credentials_request.html b/idhub/templates/idhub/user/credentials_request.html index 6dc720d..698ece5 100644 --- a/idhub/templates/idhub/user/credentials_request.html +++ b/idhub/templates/idhub/user/credentials_request.html @@ -20,6 +20,7 @@
{% endif %} +{% if form.if_credentials %}
{% bootstrap_form form %} @@ -29,6 +30,12 @@ {% trans "Cancel" %}
- +{% else %} +
+
+ {% trans 'Sorry no there are credentials enabled' %} +
+
+{% endif %} {% endblock %} diff --git a/idhub/user/forms.py b/idhub/user/forms.py index 654a936..b418b54 100644 --- a/idhub/user/forms.py +++ b/idhub/user/forms.py @@ -86,6 +86,7 @@ class RequestCredentialForm(forms.Form): self.user = kwargs.pop('user', None) self.lang = kwargs.pop('lang', None) self._domain = kwargs.pop('domain', None) + self.if_credentials = kwargs.pop('if_credentials', None) super().__init__(*args, **kwargs) self.fields['did'].choices = [ (x.did, x.label) for x in DID.objects.filter(user=self.user) @@ -130,6 +131,7 @@ class DemandAuthorizationForm(forms.Form): def __init__(self, *args, **kwargs): self.user = kwargs.pop('user', None) + self.if_credentials = kwargs.pop('if_credentials', None) super().__init__(*args, **kwargs) self.fields['organization'].choices = [ (x.id, x.name) for x in Organization.objects.exclude( diff --git a/idhub/user/views.py b/idhub/user/views.py index 97e3993..6db3500 100644 --- a/idhub/user/views.py +++ b/idhub/user/views.py @@ -392,18 +392,26 @@ class CredentialsRequestView(MyWallet, FormView): form_class = RequestCredentialForm success_url = reverse_lazy('idhub:user_credentials') - def get(self, request, *args, **kwargs): - response = super().get(request, *args, **kwargs) - if not cache.get("KEY_DIDS"): - return redirect(reverse_lazy('idhub:user_waiting')) + def get(self, *args, **kwargs): + response = super().get(*args, **kwargs) + if not DID.objects.filter(user=self.request.user).exists(): + return redirect(reverse_lazy('idhub:user_dids_new')) + return response + def get_form_kwargs(self): kwargs = super().get_form_kwargs() + self.if_credentials = VerificableCredential.objects.filter( + user=self.request.user, + status=VerificableCredential.Status.ENABLED.value, + ).exists() + kwargs['user'] = self.request.user kwargs['lang'] = self.request.LANGUAGE_CODE domain = "{}://{}".format(self.request.scheme, self.request.get_host()) kwargs['domain'] = domain + kwargs['if_credentials'] = self.if_credentials return kwargs def form_valid(self, form): @@ -427,9 +435,26 @@ class DemandAuthorizationView(MyWallet, FormView): form_class = DemandAuthorizationForm success_url = reverse_lazy('idhub:user_demand_authorization') + def get(self, *args, **kwargs): + response = super().get(*args, **kwargs) + creds_enable = VerificableCredential.objects.filter( + user=self.request.user, + status=VerificableCredential.Status.ENABLED.value, + ).exists() + + if not self.if_credentials and creds_enable: + return redirect(reverse_lazy('idhub:user_credentials_request')) + return response + def get_form_kwargs(self): kwargs = super().get_form_kwargs() + self.if_credentials = VerificableCredential.objects.filter( + user=self.request.user, + status=VerificableCredential.Status.ISSUED.value, + ).exists() + kwargs['user'] = self.request.user + kwargs['if_credentials'] = self.if_credentials return kwargs def form_valid(self, form): diff --git a/oidc4vp/models.py b/oidc4vp/models.py index 2ed3d30..35085fd 100644 --- a/oidc4vp/models.py +++ b/oidc4vp/models.py @@ -286,10 +286,10 @@ class OAuth2VPToken(models.Model): } verification = json.loads(self.result_verify) if verification.get('errors') or verification.get('warnings'): - response["verify"] = "Error, Verification Failed" + response["verify"] = "Error, {}".format(_("Failed verification")) return response - response["verify"] = "Ok, Verification correct" + response["verify"] = "Ok, {}".format(_("Correct verification")) url = self.get_redirect_url() if url: response["redirect_uri"] = url diff --git a/oidc4vp/templates/email/verify_email.html b/oidc4vp/templates/email/verify_email.html new file mode 100644 index 0000000..6a5b3b2 --- /dev/null +++ b/oidc4vp/templates/email/verify_email.html @@ -0,0 +1,10 @@ +Hola, hay una nueva verificación en el servicio de verificación Idhub {{ domain }} +
+El código asociado a esta verificación es: {{ code }} +
+estos son los datos de la verificación: +
+{{ verification|safe }} + +
+Muchas gracias diff --git a/oidc4vp/templates/email/verify_email.txt b/oidc4vp/templates/email/verify_email.txt new file mode 100644 index 0000000..b20596c --- /dev/null +++ b/oidc4vp/templates/email/verify_email.txt @@ -0,0 +1,6 @@ +Hola, hay una nueva verificación en el servicio de verificación Idhub {{ domain }} +El código asociado a esta verificación es: {{ code }} +estos son los datos de la verificación: +{{ verification|safe }} + +Muchas gracias diff --git a/oidc4vp/templates/email/verify_subject.txt b/oidc4vp/templates/email/verify_subject.txt new file mode 100644 index 0000000..c7a2a02 --- /dev/null +++ b/oidc4vp/templates/email/verify_subject.txt @@ -0,0 +1 @@ +Nueva verificacion en {{ dominio }} diff --git a/oidc4vp/templates/received_code.html b/oidc4vp/templates/received_code.html new file mode 100644 index 0000000..dc03976 --- /dev/null +++ b/oidc4vp/templates/received_code.html @@ -0,0 +1,72 @@ + +{% load i18n static %} + + + + + + + + + + {% block title %}{% if title %}{{ title }} – {% endif %}Pangea{% endblock %} + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+
+ {% trans 'Thank you, we are received your presentation correctly.' %} +
+
+
+
+ +
+
+ +
+
+
+ + diff --git a/oidc4vp/urls.py b/oidc4vp/urls.py index d7b79be..ccef7af 100644 --- a/oidc4vp/urls.py +++ b/oidc4vp/urls.py @@ -13,4 +13,6 @@ urlpatterns = [ name="authorize"), path('allow_code', views.AllowCodeView.as_view(), name="allow_code"), + path('received_code', views.ReceivedCodeView.as_view(), + name="received_code"), ] diff --git a/oidc4vp/views.py b/oidc4vp/views.py index 359a638..851c652 100644 --- a/oidc4vp/views.py +++ b/oidc4vp/views.py @@ -235,7 +235,17 @@ class AllowCodeView(View): promotion = self.authorization.promotions.first() if not promotion: - raise Http404("Page not Found!") + return redirect(reverse_lazy('oidc4vp:received_code')) return redirect(promotion.get_url(code)) + +class ReceivedCodeView(View): + template_name = "received_code.html" + + def get(self, request, *args, **kwargs): + self.context = {} + template = loader.get_template( + self.template_name, + ).render() + return HttpResponse(template)