Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#3215] Prefill with bewindvoering/machtigen #3241

Merged
merged 13 commits into from
Jul 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/manual/forms/form_fields.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,15 @@ Registratie
naar het achterliggende registratie systeem, dan kunt u hier een attribuut
kiezen dat beschikbaar is in het achterliggende registratie systeem.

Prefill
-------

* **Plugin**: Welke prefill plugin te gebruiken om data op te halen over de persoon/het bedrijf die ingelogd is.
* **Pluginattribuut**: Welk attribuut van de prefill-backend data te gebruiken om deze component voorin te vullen.
* **Identifier rol**: Bij DigiD Machtigen of eHekerkenning zijn meerdere rollen actief: de gemachtigde (persoon die het
formulier invult), of de 'geauthenticeerde' (persoon of bedrijf voor wie het formulier ingevuld wordt). Deze optie stelt in
voor welke van deze rollen de relevante gegevens voor het geselecteerde attribuut opgevraagd worden.


Globale configuratieopties
==========================
Expand Down
12 changes: 12 additions & 0 deletions src/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7091,6 +7091,13 @@ components:
description: Which attribute from the prefill response should be used to
fill this variable
maxLength: 200
prefillIdentifierRole:
allOf:
- $ref: '#/components/schemas/PrefillIdentifierRoleEnum'
description: In case that multiple identifiers are returned (in the case
of eHerkenning bewindvoering and DigiD Machtigen), should the prefill
data related to the main identifier be used, or that related to the authorised
person?
dataType:
allOf:
- $ref: '#/components/schemas/DataTypeEnum'
Expand Down Expand Up @@ -7929,6 +7936,11 @@ components:
required:
- id
- label
PrefillIdentifierRoleEnum:
enum:
- main
- authorised_person
type: string
PrefillPlugin:
type: object
properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,19 @@ class DigiDMachtigenOIDCAuthentication(OIDCAuthentication):

def add_claims_to_sessions_if_not_cosigning(self, claim, request):
# set the session auth key only if we're not co-signing
if claim and CO_SIGN_PARAMETER not in request.GET:
config = OpenIDConnectDigiDMachtigenConfig.get_solo()
request.session[FORM_AUTH_SESSION_KEY] = {
"plugin": self.identifier,
"attribute": self.provides_auth,
"value": claim[config.vertegenwoordigde_claim_name],
"machtigen": request.session[DIGID_MACHTIGEN_OIDC_AUTH_SESSION_KEY],
}
if not claim or CO_SIGN_PARAMETER in request.GET:
return
SilviaAmAm marked this conversation as resolved.
Show resolved Hide resolved

config = self.config_class.get_solo()
machtigen_data = request.session[self.session_key]
request.session[FORM_AUTH_SESSION_KEY] = {
"plugin": self.identifier,
"attribute": self.provides_auth,
"value": claim[config.vertegenwoordigde_claim_name],
"machtigen": {
"identifier_value": machtigen_data.get(config.gemachtigde_claim_name)
},
}

def get_label(self) -> str:
return "DigiD Machtigen"
Expand All @@ -179,16 +184,22 @@ class EHerkenningBewindvoeringOIDCAuthentication(OIDCAuthentication):

def add_claims_to_sessions_if_not_cosigning(self, claim, request):
# set the session auth key only if we're not co-signing
if claim and CO_SIGN_PARAMETER not in request.GET:
config = self.config_class.get_solo()
request.session[FORM_AUTH_SESSION_KEY] = {
"plugin": self.identifier,
"attribute": self.provides_auth,
"value": claim[config.vertegenwoordigde_company_claim_name],
"machtigen": request.session[
EHERKENNING_BEWINDVOERING_OIDC_AUTH_SESSION_KEY
],
}
if not claim or CO_SIGN_PARAMETER in request.GET:
return

config = self.config_class.get_solo()
machtigen_data = request.session[self.session_key]
request.session[FORM_AUTH_SESSION_KEY] = {
"plugin": self.identifier,
"attribute": self.provides_auth,
"value": claim[config.vertegenwoordigde_company_claim_name],
"machtigen": {
# TODO So far the only possibility is that this is a BSN.
"identifier_value": machtigen_data.get(
config.gemachtigde_person_claim_name
)
},
}

def get_label(self) -> str:
return "eHerkenning bewindvoering"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,29 @@
import requests_mock
from furl import furl
from rest_framework import status
from rest_framework.test import APIRequestFactory

from digid_eherkenning_oidc_generics.models import (
OpenIDConnectDigiDMachtigenConfig,
OpenIDConnectEHerkenningBewindvoeringConfig,
OpenIDConnectPublicConfig,
)
from openforms.authentication.constants import (
CO_SIGN_PARAMETER,
FORM_AUTH_SESSION_KEY,
AuthAttribute,
)
from openforms.authentication.contrib.digid_eherkenning_oidc.constants import (
DIGID_MACHTIGEN_OIDC_AUTH_SESSION_KEY,
EHERKENNING_BEWINDVOERING_OIDC_AUTH_SESSION_KEY,
)
from openforms.authentication.contrib.digid_eherkenning_oidc.plugin import (
DigiDMachtigenOIDCAuthentication,
EHerkenningBewindvoeringOIDCAuthentication,
)
from openforms.authentication.views import BACKEND_OUTAGE_RESPONSE_PARAMETER
from openforms.forms.tests.factories import FormFactory
from openforms.submissions.tests.mixins import SubmissionsMixin

default_config = dict(
enabled=True,
Expand Down Expand Up @@ -318,3 +334,115 @@ def test_redirect_with_keycloak_identity_provider_hint(self, m_get_solo):
f"http://testserver{reverse('digid_machtigen_oidc:oidc_authentication_callback')}",
)
self.assertEqual(query_params["kc_idp_hint"], "oidc-digid-machtigen")


class AddClaimsToSessionTests(SubmissionsMixin, TestCase):
def test_handle_return_without_claim_eherkenning_bewindvoering(self):
factory = APIRequestFactory()
request = factory.get("/xyz")
request.session = {}

plugin = EHerkenningBewindvoeringOIDCAuthentication(identifier="boh")
plugin.add_claims_to_sessions_if_not_cosigning(claim="", request=request)

self.assertNotIn(FORM_AUTH_SESSION_KEY, request.session)

def test_handle_return_with_cosign_param_eherkenning_bewindvoering(self):
factory = APIRequestFactory()
request = factory.get(f"/xyz?{CO_SIGN_PARAMETER}=tralala")
request.session = {}

plugin = EHerkenningBewindvoeringOIDCAuthentication(identifier="boh")
plugin.add_claims_to_sessions_if_not_cosigning(claim="tralala", request=request)

self.assertNotIn(FORM_AUTH_SESSION_KEY, request.session)

def test_handle_return_without_claim_digid_machtigen(self):
factory = APIRequestFactory()
request = factory.get("/xyz")
request.session = {}

plugin = DigiDMachtigenOIDCAuthentication(identifier="boh")
plugin.add_claims_to_sessions_if_not_cosigning(claim="", request=request)

self.assertNotIn(FORM_AUTH_SESSION_KEY, request.session)

def test_handle_return_with_cosign_param_digi_machtigen(self):
factory = APIRequestFactory()
request = factory.get(f"/xyz?{CO_SIGN_PARAMETER}=tralala")
request.session = {}

plugin = DigiDMachtigenOIDCAuthentication(identifier="boh")
plugin.add_claims_to_sessions_if_not_cosigning(claim="tralala", request=request)

self.assertNotIn(FORM_AUTH_SESSION_KEY, request.session)

def test_handle_return_eherkenning_bewindvoering(self):
factory = APIRequestFactory()
request = factory.get("/xyz")
request.session = {
EHERKENNING_BEWINDVOERING_OIDC_AUTH_SESSION_KEY: {
"aanvrager.bsn": "222222222"
}
}

plugin = EHerkenningBewindvoeringOIDCAuthentication(identifier="boh")

with patch(
"openforms.authentication.contrib.digid_eherkenning_oidc.plugin.OpenIDConnectEHerkenningBewindvoeringConfig.get_solo",
return_value=OpenIDConnectEHerkenningBewindvoeringConfig(
vertegenwoordigde_company_claim_name="gemachtige.kvk",
gemachtigde_person_claim_name="aanvrager.bsn",
),
):
plugin.add_claims_to_sessions_if_not_cosigning(
claim={
"gemachtige.kvk": "111111111",
},
request=request,
)

self.assertIn(FORM_AUTH_SESSION_KEY, request.session)
self.assertEqual(
{
"plugin": "boh",
"attribute": AuthAttribute.kvk,
"value": "111111111",
"machtigen": {"identifier_value": "222222222"},
},
request.session[FORM_AUTH_SESSION_KEY],
)

def test_handle_return_digid_machtigen(self):
factory = APIRequestFactory()
request = factory.get("/xyz")
request.session = {
DIGID_MACHTIGEN_OIDC_AUTH_SESSION_KEY: {"aanvrager.bsn": "222222222"}
}

plugin = DigiDMachtigenOIDCAuthentication(identifier="boh")

with patch(
"openforms.authentication.contrib.digid_eherkenning_oidc.plugin.OpenIDConnectDigiDMachtigenConfig.get_solo",
return_value=OpenIDConnectDigiDMachtigenConfig(
vertegenwoordigde_claim_name="gemachtige.bsn",
gemachtigde_claim_name="aanvrager.bsn",
),
):
plugin.add_claims_to_sessions_if_not_cosigning(
claim={
"gemachtige.bsn": "111111111",
},
request=request,
)

self.assertIn(FORM_AUTH_SESSION_KEY, request.session)
self.assertEqual(
{
"plugin": "boh",
"attribute": AuthAttribute.bsn,
"value": "111111111",
"machtigen": {"identifier_value": "222222222"},
},
request.session[FORM_AUTH_SESSION_KEY],
)
25 changes: 25 additions & 0 deletions src/openforms/authentication/tests/test_signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,31 @@ def test_setting_auth_attributes_flips_hashed_flag(self):
self.assertEqual(submission.auth_info.value, "123456789")
self.assertFalse(submission.auth_info.attribute_hashed)

def test_auth_with_digid_machtigen(self):
submission = SubmissionFactory.create(
form__authentication_backends=["digid_machtigen_oidc"]
)
user = UserFactory()
request = factory.get("/foo")
request.user = user
request.session = {
FORM_AUTH_SESSION_KEY: {
"plugin": "digid_machtigen_oidc",
"attribute": "bsn",
"value": "123123123",
"machtigen": {"identifier_value": "123456782"},
}
}

set_auth_attribute_on_session(sender=None, instance=submission, request=request)

submission.refresh_from_db()

self.assertTrue(submission.is_authenticated)
self.assertEqual(
submission.auth_info.machtigen["identifier_value"], "123456782"
)


class SetCosignDataTests(APITestCase):
def test_set_cosigner_data(self):
Expand Down
2 changes: 2 additions & 0 deletions src/openforms/forms/admin/form_variable.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class FormVariableAdmin(admin.ModelAdmin):
"source",
"prefill_plugin",
"prefill_attribute",
"prefill_identifier_role",
"data_type",
"is_sensitive_data",
"initial_value",
Expand All @@ -29,6 +30,7 @@ class FormVariableAdmin(admin.ModelAdmin):
"source",
"prefill_plugin",
"prefill_attribute",
"prefill_identifier_role",
"data_type",
"data_format",
"is_sensitive_data",
Expand Down
1 change: 1 addition & 0 deletions src/openforms/forms/api/serializers/form_variable.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ class Meta:
"service_fetch_configuration",
"prefill_plugin",
"prefill_attribute",
"prefill_identifier_role",
"data_type",
"data_format",
"is_sensitive_data",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 3.2.20 on 2023-07-07 12:06

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("forms", "0083_alter_form_is_appointment"),
]

operations = [
migrations.AddField(
model_name="formvariable",
name="prefill_identifier_role",
field=models.CharField(
choices=[("main", "Main"), ("authorised_person", "Authorised person")],
default="main",
help_text="In case that multiple identifiers are returned (in the case of eHerkenning bewindvoering and DigiD Machtigen), should the prefill data related to the main identifier be used, or that related to the authorised person?",
max_length=100,
verbose_name="prefill identifier role",
),
),
]
17 changes: 17 additions & 0 deletions src/openforms/forms/models/form_variable.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
is_layout_component,
iter_components,
)
from openforms.prefill.constants import IdentifierRoles
from openforms.variables.constants import FormVariableDataTypes, FormVariableSources
from openforms.variables.utils import check_initial_value

Expand Down Expand Up @@ -87,6 +88,12 @@ def create_for_formstep(self, form_step: "FormStep") -> List["FormVariable"]:
default="",
skip_exc=KeyError,
),
prefill_identifier_role=glom(
component,
Path("prefill", "identifierRole"),
default=IdentifierRoles.main,
skip_exc=KeyError,
),
key=component["key"],
name=component.get("label") or component["key"],
is_sensitive_data=component.get("isSensitiveData", False),
Expand Down Expand Up @@ -154,6 +161,16 @@ class FormVariable(models.Model):
blank=True,
max_length=200,
)
prefill_identifier_role = models.CharField(
verbose_name=_("prefill identifier role"),
help_text=_(
"In case that multiple identifiers are returned (in the case of eHerkenning bewindvoering and DigiD "
"Machtigen), should the prefill data related to the main identifier be used, or that related to the authorised person?"
),
choices=IdentifierRoles.choices,
default=IdentifierRoles.main,
max_length=100,
)
data_type = models.CharField(
verbose_name=_("data type"),
help_text=_("The type of the value that will be associated with this variable"),
Expand Down
Loading
Loading